@tinycloud/operations 0.3.4-beta.0 → 0.3.4-beta.2
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/artifacts.cjs +84 -71
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.js +84 -71
- package/dist/artifacts.js.map +1 -1
- package/dist/cli-runtime.cjs +84 -71
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.js +84 -71
- package/dist/cli-runtime.js.map +1 -1
- package/dist/index.cjs +84 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +84 -71
- package/dist/index.js.map +1 -1
- package/dist/profile.cjs.map +1 -1
- package/dist/profile.js.map +1 -1
- package/dist/state.cjs +9 -4
- package/dist/state.cjs.map +1 -1
- package/dist/state.js +9 -4
- package/dist/state.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1256,10 +1256,14 @@ async function responseError(service, message, response) {
|
|
|
1256
1256
|
}
|
|
1257
1257
|
} catch {
|
|
1258
1258
|
}
|
|
1259
|
-
|
|
1259
|
+
const error = wrapError(
|
|
1260
1260
|
service,
|
|
1261
1261
|
new Error(`${message}: ${response.status} ${detail}`)
|
|
1262
1262
|
);
|
|
1263
|
+
return {
|
|
1264
|
+
...error,
|
|
1265
|
+
meta: { ...error.meta, status: response.status, statusText: response.statusText }
|
|
1266
|
+
};
|
|
1263
1267
|
}
|
|
1264
1268
|
function isAbortError(error) {
|
|
1265
1269
|
return error instanceof DOMException && error.name === "AbortError";
|
|
@@ -3079,7 +3083,7 @@ var init_dist2 = __esm({
|
|
|
3079
3083
|
return err(
|
|
3080
3084
|
storageQuotaExceededError(
|
|
3081
3085
|
"kv",
|
|
3082
|
-
`Storage quota exceeded for key
|
|
3086
|
+
`Storage quota exceeded for key ${JSON.stringify(key)}: ${errorText}`,
|
|
3083
3087
|
{
|
|
3084
3088
|
status: response.status,
|
|
3085
3089
|
...quotaInfo ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes } : {}
|
|
@@ -3092,7 +3096,7 @@ var init_dist2 = __esm({
|
|
|
3092
3096
|
return err(
|
|
3093
3097
|
storageLimitReachedError(
|
|
3094
3098
|
"kv",
|
|
3095
|
-
`Storage limit reached for key
|
|
3099
|
+
`Storage limit reached for key ${JSON.stringify(key)}: ${errorText}`,
|
|
3096
3100
|
{
|
|
3097
3101
|
status: response.status,
|
|
3098
3102
|
...quotaInfo ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes } : {}
|
|
@@ -3378,12 +3382,11 @@ var init_dist2 = __esm({
|
|
|
3378
3382
|
if (!response.ok) {
|
|
3379
3383
|
const errorText = await response.text();
|
|
3380
3384
|
if (response.status === 401 || response.status === 403) {
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
}));
|
|
3385
|
+
return this.authorizationFailure(
|
|
3386
|
+
`Failed to batch read ${keys.length} key(s)`,
|
|
3387
|
+
response,
|
|
3388
|
+
errorText
|
|
3389
|
+
);
|
|
3387
3390
|
}
|
|
3388
3391
|
if (response.status === 413) {
|
|
3389
3392
|
return err(serviceError(
|
|
@@ -3482,23 +3485,39 @@ var init_dist2 = __esm({
|
|
|
3482
3485
|
} catch {
|
|
3483
3486
|
}
|
|
3484
3487
|
if (response.status === 401 || response.status === 403) {
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
}));
|
|
3488
|
+
return this.authorizationFailure(
|
|
3489
|
+
`Failed to create signed read URL for key ${JSON.stringify(key)}`,
|
|
3490
|
+
response,
|
|
3491
|
+
errorText
|
|
3492
|
+
);
|
|
3491
3493
|
}
|
|
3492
3494
|
const code = response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;
|
|
3493
3495
|
return err(
|
|
3494
3496
|
serviceError(
|
|
3495
3497
|
code,
|
|
3496
|
-
`Failed to create signed read URL for key
|
|
3498
|
+
`Failed to create signed read URL for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
|
|
3497
3499
|
"kv",
|
|
3498
3500
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3499
3501
|
)
|
|
3500
3502
|
);
|
|
3501
3503
|
}
|
|
3504
|
+
/**
|
|
3505
|
+
* AUTH_UNAUTHORIZED for a 401/403 response. The message keeps the HTTP
|
|
3506
|
+
* status and the server text (`<context>: <status> - <text>`, the same
|
|
3507
|
+
* shape as every other KV failure) so callers that rethrow only the message
|
|
3508
|
+
* still see the status; `meta.status` carries it for typed callers.
|
|
3509
|
+
* Resource/ability hints are parsed from the raw body, never the message.
|
|
3510
|
+
*/
|
|
3511
|
+
authorizationFailure(context, response, errorText, extraMeta = {}) {
|
|
3512
|
+
const { resource, action } = parseAuthError(errorText);
|
|
3513
|
+
const detail = errorText.trim().length > 0 ? errorText : response.statusText || "authorization failed";
|
|
3514
|
+
return err(authUnauthorizedError("kv", `${context}: ${response.status} - ${detail}`, {
|
|
3515
|
+
status: response.status,
|
|
3516
|
+
...action && { requiredAction: action },
|
|
3517
|
+
...resource && { resource },
|
|
3518
|
+
...extraMeta
|
|
3519
|
+
}));
|
|
3520
|
+
}
|
|
3502
3521
|
normalizeSignedReadUrlResponse(data) {
|
|
3503
3522
|
if (!data || typeof data !== "object") {
|
|
3504
3523
|
return void 0;
|
|
@@ -3541,14 +3560,13 @@ var init_dist2 = __esm({
|
|
|
3541
3560
|
if (!response.ok) {
|
|
3542
3561
|
if (response.status === 401 || response.status === 403) {
|
|
3543
3562
|
const errorText2 = await response.text();
|
|
3544
|
-
const { resource, action } = parseAuthError(errorText2);
|
|
3545
3563
|
const permissionHint = parsePermissionHintFromErrorText(errorText2);
|
|
3546
|
-
return
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3564
|
+
return this.authorizationFailure(
|
|
3565
|
+
`Failed to get key ${JSON.stringify(key)}`,
|
|
3566
|
+
response,
|
|
3567
|
+
errorText2,
|
|
3568
|
+
permissionHint === void 0 ? {} : { permissionHint }
|
|
3569
|
+
);
|
|
3552
3570
|
}
|
|
3553
3571
|
if (response.status === 404) {
|
|
3554
3572
|
return this.classifyNotFound(response, key);
|
|
@@ -3557,7 +3575,7 @@ var init_dist2 = __esm({
|
|
|
3557
3575
|
if (response.status === 413) {
|
|
3558
3576
|
return err(serviceError(
|
|
3559
3577
|
ErrorCodes.KV_RESPONSE_TOO_LARGE,
|
|
3560
|
-
`KV value at key
|
|
3578
|
+
`KV value at key ${JSON.stringify(key)} exceeds the requested response limit`,
|
|
3561
3579
|
"kv",
|
|
3562
3580
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3563
3581
|
));
|
|
@@ -3565,7 +3583,7 @@ var init_dist2 = __esm({
|
|
|
3565
3583
|
return err(
|
|
3566
3584
|
serviceError(
|
|
3567
3585
|
ErrorCodes.NETWORK_ERROR,
|
|
3568
|
-
`Failed to get key
|
|
3586
|
+
`Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
|
|
3569
3587
|
"kv",
|
|
3570
3588
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3571
3589
|
)
|
|
@@ -3621,21 +3639,18 @@ var init_dist2 = __esm({
|
|
|
3621
3639
|
}
|
|
3622
3640
|
);
|
|
3623
3641
|
if (response.status === 401 || response.status === 403) {
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
...requiredAction && { requiredAction },
|
|
3630
|
-
...resource && { resource }
|
|
3631
|
-
}));
|
|
3642
|
+
return this.authorizationFailure(
|
|
3643
|
+
`Failed to put key ${JSON.stringify(key)}`,
|
|
3644
|
+
response,
|
|
3645
|
+
await response.text()
|
|
3646
|
+
);
|
|
3632
3647
|
}
|
|
3633
3648
|
if (!response.ok) {
|
|
3634
3649
|
const errorText = await response.text();
|
|
3635
3650
|
if (response.status === 412) {
|
|
3636
3651
|
return err(serviceError(
|
|
3637
3652
|
ErrorCodes.KV_PRECONDITION_FAILED,
|
|
3638
|
-
`KV precondition failed for key
|
|
3653
|
+
`KV precondition failed for key ${JSON.stringify(key)}`,
|
|
3639
3654
|
"kv",
|
|
3640
3655
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3641
3656
|
));
|
|
@@ -3643,7 +3658,7 @@ var init_dist2 = __esm({
|
|
|
3643
3658
|
if (response.status === 503 && (options?.ifMatch !== void 0 || options?.ifNoneMatch !== void 0)) {
|
|
3644
3659
|
return err(serviceError(
|
|
3645
3660
|
ErrorCodes.KV_CONFLICT,
|
|
3646
|
-
`Concurrent KV update conflicted for key
|
|
3661
|
+
`Concurrent KV update conflicted for key ${JSON.stringify(key)}`,
|
|
3647
3662
|
"kv",
|
|
3648
3663
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3649
3664
|
));
|
|
@@ -3659,7 +3674,7 @@ var init_dist2 = __esm({
|
|
|
3659
3674
|
return err(
|
|
3660
3675
|
serviceError(
|
|
3661
3676
|
ErrorCodes.KV_WRITE_FAILED,
|
|
3662
|
-
`Failed to put key
|
|
3677
|
+
`Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
|
|
3663
3678
|
"kv",
|
|
3664
3679
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3665
3680
|
)
|
|
@@ -3753,12 +3768,11 @@ var init_dist2 = __esm({
|
|
|
3753
3768
|
);
|
|
3754
3769
|
}
|
|
3755
3770
|
if (response.status === 401 || response.status === 403) {
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
}));
|
|
3771
|
+
return this.authorizationFailure(
|
|
3772
|
+
`Failed to batch put ${items.length} key(s)`,
|
|
3773
|
+
response,
|
|
3774
|
+
errorText
|
|
3775
|
+
);
|
|
3762
3776
|
}
|
|
3763
3777
|
const quotaError = this.handleQuotaErrorResponse(
|
|
3764
3778
|
response,
|
|
@@ -3879,13 +3893,11 @@ var init_dist2 = __esm({
|
|
|
3879
3893
|
);
|
|
3880
3894
|
if (!response.ok) {
|
|
3881
3895
|
if (response.status === 401) {
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
...resource && { resource }
|
|
3888
|
-
}));
|
|
3896
|
+
return this.authorizationFailure(
|
|
3897
|
+
"Failed to list keys",
|
|
3898
|
+
response,
|
|
3899
|
+
await response.text()
|
|
3900
|
+
);
|
|
3889
3901
|
}
|
|
3890
3902
|
const errorText = await response.text();
|
|
3891
3903
|
return err(
|
|
@@ -3934,13 +3946,11 @@ var init_dist2 = __esm({
|
|
|
3934
3946
|
);
|
|
3935
3947
|
if (!response.ok) {
|
|
3936
3948
|
if (response.status === 401) {
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
...resource && { resource }
|
|
3943
|
-
}));
|
|
3949
|
+
return this.authorizationFailure(
|
|
3950
|
+
`Failed to delete key ${JSON.stringify(key)}`,
|
|
3951
|
+
response,
|
|
3952
|
+
await response.text()
|
|
3953
|
+
);
|
|
3944
3954
|
}
|
|
3945
3955
|
if (response.status === 404) {
|
|
3946
3956
|
return this.classifyNotFound(response, key);
|
|
@@ -3949,7 +3959,7 @@ var init_dist2 = __esm({
|
|
|
3949
3959
|
if (response.status === 412) {
|
|
3950
3960
|
return err(serviceError(
|
|
3951
3961
|
ErrorCodes.KV_PRECONDITION_FAILED,
|
|
3952
|
-
`KV precondition failed for key
|
|
3962
|
+
`KV precondition failed for key ${JSON.stringify(key)}`,
|
|
3953
3963
|
"kv",
|
|
3954
3964
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3955
3965
|
));
|
|
@@ -3957,7 +3967,7 @@ var init_dist2 = __esm({
|
|
|
3957
3967
|
if (response.status === 503 && options?.ifMatch !== void 0) {
|
|
3958
3968
|
return err(serviceError(
|
|
3959
3969
|
ErrorCodes.KV_CONFLICT,
|
|
3960
|
-
`Concurrent KV delete conflicted for key
|
|
3970
|
+
`Concurrent KV delete conflicted for key ${JSON.stringify(key)}`,
|
|
3961
3971
|
"kv",
|
|
3962
3972
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3963
3973
|
));
|
|
@@ -3965,7 +3975,7 @@ var init_dist2 = __esm({
|
|
|
3965
3975
|
return err(
|
|
3966
3976
|
serviceError(
|
|
3967
3977
|
ErrorCodes.NETWORK_ERROR,
|
|
3968
|
-
`Failed to delete key
|
|
3978
|
+
`Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
|
|
3969
3979
|
"kv",
|
|
3970
3980
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3971
3981
|
)
|
|
@@ -3998,13 +4008,11 @@ var init_dist2 = __esm({
|
|
|
3998
4008
|
);
|
|
3999
4009
|
if (!response.ok) {
|
|
4000
4010
|
if (response.status === 401) {
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
...resource && { resource }
|
|
4007
|
-
}));
|
|
4011
|
+
return this.authorizationFailure(
|
|
4012
|
+
`Failed to get metadata for key ${JSON.stringify(key)}`,
|
|
4013
|
+
response,
|
|
4014
|
+
await response.text()
|
|
4015
|
+
);
|
|
4008
4016
|
}
|
|
4009
4017
|
if (response.status === 404) {
|
|
4010
4018
|
return this.classifyNotFound(response, key);
|
|
@@ -4013,7 +4021,7 @@ var init_dist2 = __esm({
|
|
|
4013
4021
|
return err(
|
|
4014
4022
|
serviceError(
|
|
4015
4023
|
ErrorCodes.NETWORK_ERROR,
|
|
4016
|
-
`Failed to get metadata for key
|
|
4024
|
+
`Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
|
|
4017
4025
|
"kv",
|
|
4018
4026
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
4019
4027
|
)
|
|
@@ -7220,9 +7228,12 @@ async function acquireProfileLock(profile, options) {
|
|
|
7220
7228
|
const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_LOCK_MS;
|
|
7221
7229
|
const startedAt = Date.now();
|
|
7222
7230
|
const lockPath = profileLockPath(profile);
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7231
|
+
const directory = profilePath(profile);
|
|
7232
|
+
await (0, import_promises.mkdir)(directory, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
7233
|
+
for (const path of [tinycloudHomePath(), profilesPath(), directory]) {
|
|
7234
|
+
await (0, import_promises.chmod)(path, PRIVATE_DIR_MODE).catch((error) => {
|
|
7235
|
+
if (path !== directory || !isErrno(error, "ENOENT")) throw error;
|
|
7236
|
+
});
|
|
7226
7237
|
}
|
|
7227
7238
|
while (true) {
|
|
7228
7239
|
const token = (0, import_node_crypto.randomUUID)();
|
|
@@ -7245,7 +7256,9 @@ async function publishProfileLock(profile, lockPath, token) {
|
|
|
7245
7256
|
await (0, import_promises.mkdir)(lockPath, { mode: PRIVATE_DIR_MODE });
|
|
7246
7257
|
} catch (error) {
|
|
7247
7258
|
if (isErrno(error, "EEXIST")) return false;
|
|
7248
|
-
throw error;
|
|
7259
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
7260
|
+
await (0, import_promises.mkdir)(profilePath(profile), { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
7261
|
+
return false;
|
|
7249
7262
|
}
|
|
7250
7263
|
await waitForTestBarrier(TEST_LOCK_PUBLISH_BARRIER_DIR, profile);
|
|
7251
7264
|
const staged = (0, import_node_path.join)((0, import_node_path.dirname)(lockPath), `.lock-owner-${token}.tmp`);
|