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