mnemospark 0.1.17 → 0.1.18
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/cli.js +275 -248
- package/dist/cli.js.map +1 -1
- package/dist/index.js +275 -248
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3010,300 +3010,327 @@ function formatStorageLsUserMessage(result, requestedObjectKey) {
|
|
|
3010
3010
|
return `${objectId} with ${requestedObjectKey} is ${result.size_bytes} in ${result.bucket}`;
|
|
3011
3011
|
}
|
|
3012
3012
|
function createCloudCommand(options = {}) {
|
|
3013
|
-
const backupBuilder = options.buildBackupObjectFn ?? buildBackupObject;
|
|
3014
|
-
const requestPriceStorageQuote = options.requestPriceStorageQuoteFn ?? requestPriceStorageViaProxy;
|
|
3015
|
-
const requestStorageUpload = options.requestStorageUploadFn ?? requestStorageUploadViaProxy;
|
|
3016
|
-
const requestStorageUploadConfirm = options.requestStorageUploadConfirmFn ?? requestStorageUploadConfirmViaProxy;
|
|
3017
|
-
const resolveWalletKey = options.resolveWalletPrivateKeyFn ?? resolveWalletPrivateKey;
|
|
3018
|
-
const createPayment = options.createPaymentFetchFn ?? createPaymentFetch;
|
|
3019
|
-
const fetchImpl = options.fetchImpl ?? fetch;
|
|
3020
|
-
const nowDateFn = options.nowDateFn ?? (() => /* @__PURE__ */ new Date());
|
|
3021
|
-
const idempotencyKeyFn = options.idempotencyKeyFn ?? randomUUID;
|
|
3022
|
-
const requestStorageLs = options.requestStorageLsFn ?? requestStorageLsViaProxy;
|
|
3023
|
-
const requestStorageDownload = options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy;
|
|
3024
|
-
const requestStorageDelete = options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy;
|
|
3025
|
-
const objectLogHomeDir = options.objectLogHomeDir ?? options.backupOptions?.homeDir;
|
|
3026
3013
|
return {
|
|
3027
3014
|
name: "mnemospark-cloud",
|
|
3028
3015
|
description: "Manage mnemospark cloud storage workflow commands",
|
|
3029
3016
|
acceptsArgs: true,
|
|
3030
3017
|
requireAuth: true,
|
|
3031
3018
|
handler: async (ctx) => {
|
|
3032
|
-
|
|
3033
|
-
|
|
3019
|
+
try {
|
|
3020
|
+
return await runCloudCommandHandler(ctx, {
|
|
3021
|
+
buildBackupObjectFn: options.buildBackupObjectFn ?? buildBackupObject,
|
|
3022
|
+
requestPriceStorageQuoteFn: options.requestPriceStorageQuoteFn ?? requestPriceStorageViaProxy,
|
|
3023
|
+
requestStorageUploadFn: options.requestStorageUploadFn ?? requestStorageUploadViaProxy,
|
|
3024
|
+
requestStorageUploadConfirmFn: options.requestStorageUploadConfirmFn ?? requestStorageUploadConfirmViaProxy,
|
|
3025
|
+
resolveWalletKeyFn: options.resolveWalletPrivateKeyFn ?? resolveWalletPrivateKey,
|
|
3026
|
+
createPaymentFetchFn: options.createPaymentFetchFn ?? createPaymentFetch,
|
|
3027
|
+
fetchImpl: options.fetchImpl ?? fetch,
|
|
3028
|
+
nowDateFn: options.nowDateFn ?? (() => /* @__PURE__ */ new Date()),
|
|
3029
|
+
idempotencyKeyFn: options.idempotencyKeyFn ?? randomUUID,
|
|
3030
|
+
requestStorageLsFn: options.requestStorageLsFn ?? requestStorageLsViaProxy,
|
|
3031
|
+
requestStorageDownloadFn: options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy,
|
|
3032
|
+
requestStorageDeleteFn: options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy,
|
|
3033
|
+
objectLogHomeDir: options.objectLogHomeDir ?? options.backupOptions?.homeDir,
|
|
3034
|
+
backupOptions: options.backupOptions,
|
|
3035
|
+
proxyQuoteOptions: options.proxyQuoteOptions,
|
|
3036
|
+
proxyUploadOptions: options.proxyUploadOptions,
|
|
3037
|
+
proxyUploadConfirmOptions: options.proxyUploadConfirmOptions,
|
|
3038
|
+
proxyStorageOptions: options.proxyStorageOptions
|
|
3039
|
+
});
|
|
3040
|
+
} catch (outerError) {
|
|
3041
|
+
const message = outerError instanceof Error ? outerError.message : typeof outerError === "string" ? outerError : "An unexpected error occurred";
|
|
3042
|
+
return { text: message.trim() || "An unexpected error occurred", isError: true };
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
};
|
|
3046
|
+
}
|
|
3047
|
+
async function runCloudCommandHandler(ctx, options) {
|
|
3048
|
+
const parsed = parseCloudArgs(ctx.args);
|
|
3049
|
+
const objectLogHomeDir = options.objectLogHomeDir;
|
|
3050
|
+
const backupBuilder = options.buildBackupObjectFn;
|
|
3051
|
+
const requestPriceStorageQuote = options.requestPriceStorageQuoteFn;
|
|
3052
|
+
const requestStorageUpload = options.requestStorageUploadFn;
|
|
3053
|
+
const requestStorageUploadConfirm = options.requestStorageUploadConfirmFn;
|
|
3054
|
+
const resolveWalletKey = options.resolveWalletKeyFn;
|
|
3055
|
+
const createPayment = options.createPaymentFetchFn;
|
|
3056
|
+
const fetchImpl = options.fetchImpl;
|
|
3057
|
+
const nowDateFn = options.nowDateFn;
|
|
3058
|
+
const idempotencyKeyFn = options.idempotencyKeyFn;
|
|
3059
|
+
const requestStorageLs = options.requestStorageLsFn;
|
|
3060
|
+
const requestStorageDownload = options.requestStorageDownloadFn;
|
|
3061
|
+
const requestStorageDelete = options.requestStorageDeleteFn;
|
|
3062
|
+
if (parsed.mode === "help" || parsed.mode === "unknown") {
|
|
3063
|
+
return {
|
|
3064
|
+
text: CLOUD_HELP_TEXT,
|
|
3065
|
+
isError: parsed.mode === "unknown"
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
if (parsed.mode === "price-storage-invalid") {
|
|
3069
|
+
return {
|
|
3070
|
+
text: `Cannot price storage: required arguments are ${REQUIRED_PRICE_STORAGE}.`,
|
|
3071
|
+
isError: true
|
|
3072
|
+
};
|
|
3073
|
+
}
|
|
3074
|
+
if (parsed.mode === "upload-invalid") {
|
|
3075
|
+
return {
|
|
3076
|
+
text: `Cannot upload storage object: required arguments are ${REQUIRED_UPLOAD}.`,
|
|
3077
|
+
isError: true
|
|
3078
|
+
};
|
|
3079
|
+
}
|
|
3080
|
+
if (parsed.mode === "ls-invalid") {
|
|
3081
|
+
return {
|
|
3082
|
+
text: `Cannot list storage object: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,
|
|
3083
|
+
isError: true
|
|
3084
|
+
};
|
|
3085
|
+
}
|
|
3086
|
+
if (parsed.mode === "download-invalid") {
|
|
3087
|
+
return {
|
|
3088
|
+
text: `Cannot download file: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,
|
|
3089
|
+
isError: true
|
|
3090
|
+
};
|
|
3091
|
+
}
|
|
3092
|
+
if (parsed.mode === "delete-invalid") {
|
|
3093
|
+
return {
|
|
3094
|
+
text: `Cannot delete file: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,
|
|
3095
|
+
isError: true
|
|
3096
|
+
};
|
|
3097
|
+
}
|
|
3098
|
+
if (parsed.mode === "backup") {
|
|
3099
|
+
try {
|
|
3100
|
+
const result = await backupBuilder(parsed.backupTarget, options.backupOptions);
|
|
3101
|
+
return {
|
|
3102
|
+
text: [
|
|
3103
|
+
`object-id: ${result.objectId}`,
|
|
3104
|
+
`object-id-hash: ${result.objectIdHash.replace(/\s/g, "")}`,
|
|
3105
|
+
`object-size: ${result.objectSizeGb}`
|
|
3106
|
+
].join("\n")
|
|
3107
|
+
};
|
|
3108
|
+
} catch (err) {
|
|
3109
|
+
if (err instanceof UnsupportedBackupPlatformError) {
|
|
3034
3110
|
return {
|
|
3035
|
-
text:
|
|
3036
|
-
isError:
|
|
3111
|
+
text: "Cloud backup is only supported on macOS and Linux.",
|
|
3112
|
+
isError: true
|
|
3037
3113
|
};
|
|
3038
3114
|
}
|
|
3039
|
-
|
|
3115
|
+
return {
|
|
3116
|
+
text: "Cannot build storage object",
|
|
3117
|
+
isError: true
|
|
3118
|
+
};
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
if (parsed.mode === "price-storage") {
|
|
3122
|
+
try {
|
|
3123
|
+
const quote = await requestPriceStorageQuote(
|
|
3124
|
+
parsed.priceStorageRequest,
|
|
3125
|
+
options.proxyQuoteOptions
|
|
3126
|
+
);
|
|
3127
|
+
await appendPriceStorageQuoteLog(quote, objectLogHomeDir);
|
|
3128
|
+
return {
|
|
3129
|
+
text: formatPriceStorageUserMessage(quote)
|
|
3130
|
+
};
|
|
3131
|
+
} catch (err) {
|
|
3132
|
+
const message = err instanceof Error ? err.message : typeof err === "string" ? err : String(err);
|
|
3133
|
+
return {
|
|
3134
|
+
text: message ? `Cannot price storage: ${message}` : "Cannot price storage",
|
|
3135
|
+
isError: true
|
|
3136
|
+
};
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
if (parsed.mode === "upload") {
|
|
3140
|
+
try {
|
|
3141
|
+
const loggedQuote = await findLoggedPriceStorageQuote(
|
|
3142
|
+
parsed.uploadRequest.quote_id,
|
|
3143
|
+
objectLogHomeDir
|
|
3144
|
+
);
|
|
3145
|
+
if (!loggedQuote) {
|
|
3040
3146
|
return {
|
|
3041
|
-
text:
|
|
3147
|
+
text: "Cannot upload storage object: quote-id not found in object.log. Run /mnemospark-cloud price-storage first.",
|
|
3042
3148
|
isError: true
|
|
3043
3149
|
};
|
|
3044
3150
|
}
|
|
3045
|
-
if (parsed.
|
|
3151
|
+
if (loggedQuote.walletAddress.toLowerCase() !== parsed.uploadRequest.wallet_address.toLowerCase() || loggedQuote.objectId !== parsed.uploadRequest.object_id || loggedQuote.objectIdHash.toLowerCase() !== parsed.uploadRequest.object_id_hash.toLowerCase()) {
|
|
3046
3152
|
return {
|
|
3047
|
-
text:
|
|
3153
|
+
text: "Cannot upload storage object: quote details do not match wallet/object arguments.",
|
|
3048
3154
|
isError: true
|
|
3049
3155
|
};
|
|
3050
3156
|
}
|
|
3051
|
-
|
|
3157
|
+
const archivePath = join5(
|
|
3158
|
+
options.backupOptions?.tmpDir ?? DEFAULT_BACKUP_DIR,
|
|
3159
|
+
parsed.uploadRequest.object_id
|
|
3160
|
+
);
|
|
3161
|
+
let archiveStats;
|
|
3162
|
+
try {
|
|
3163
|
+
archiveStats = await stat(archivePath);
|
|
3164
|
+
} catch {
|
|
3052
3165
|
return {
|
|
3053
|
-
text: `Cannot
|
|
3166
|
+
text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /mnemospark-cloud backup first.`,
|
|
3054
3167
|
isError: true
|
|
3055
3168
|
};
|
|
3056
3169
|
}
|
|
3057
|
-
if (
|
|
3170
|
+
if (!archiveStats.isFile()) {
|
|
3058
3171
|
return {
|
|
3059
|
-
text: `Cannot
|
|
3172
|
+
text: `Cannot upload storage object: local archive path is not a file (${archivePath}).`,
|
|
3060
3173
|
isError: true
|
|
3061
3174
|
};
|
|
3062
3175
|
}
|
|
3063
|
-
|
|
3176
|
+
const archiveHash = await sha256File(archivePath);
|
|
3177
|
+
if (archiveHash.toLowerCase() !== parsed.uploadRequest.object_id_hash.toLowerCase()) {
|
|
3064
3178
|
return {
|
|
3065
|
-
text:
|
|
3179
|
+
text: "Cannot upload storage object: object-id-hash does not match local archive.",
|
|
3066
3180
|
isError: true
|
|
3067
3181
|
};
|
|
3068
3182
|
}
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
`object-size: ${result.objectSizeGb}`
|
|
3077
|
-
].join("\n")
|
|
3078
|
-
};
|
|
3079
|
-
} catch (err) {
|
|
3080
|
-
if (err instanceof UnsupportedBackupPlatformError) {
|
|
3081
|
-
return {
|
|
3082
|
-
text: "Cloud backup is only supported on macOS and Linux.",
|
|
3083
|
-
isError: true
|
|
3084
|
-
};
|
|
3085
|
-
}
|
|
3086
|
-
return {
|
|
3087
|
-
text: "Cannot build storage object",
|
|
3088
|
-
isError: true
|
|
3089
|
-
};
|
|
3090
|
-
}
|
|
3183
|
+
const walletKey = await resolveWalletKey(objectLogHomeDir);
|
|
3184
|
+
const walletAccount = privateKeyToAccount5(walletKey);
|
|
3185
|
+
if (walletAccount.address.toLowerCase() !== parsed.uploadRequest.wallet_address.toLowerCase()) {
|
|
3186
|
+
return {
|
|
3187
|
+
text: `Cannot upload storage object: wallet key address ${walletAccount.address} does not match --wallet-address ${parsed.uploadRequest.wallet_address}.`,
|
|
3188
|
+
isError: true
|
|
3189
|
+
};
|
|
3091
3190
|
}
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3191
|
+
const preparedPayload = await prepareUploadPayload(
|
|
3192
|
+
archivePath,
|
|
3193
|
+
parsed.uploadRequest.wallet_address,
|
|
3194
|
+
objectLogHomeDir
|
|
3195
|
+
);
|
|
3196
|
+
const paymentFetch = createPayment(walletKey).fetch;
|
|
3197
|
+
const idempotencyKey = idempotencyKeyFn();
|
|
3198
|
+
const uploadResponse = await requestStorageUpload(
|
|
3199
|
+
{
|
|
3200
|
+
quote_id: parsed.uploadRequest.quote_id,
|
|
3201
|
+
wallet_address: parsed.uploadRequest.wallet_address,
|
|
3202
|
+
object_id: parsed.uploadRequest.object_id,
|
|
3203
|
+
object_id_hash: parsed.uploadRequest.object_id_hash,
|
|
3204
|
+
quoted_storage_price: loggedQuote.storagePrice,
|
|
3205
|
+
payload: preparedPayload.payload
|
|
3206
|
+
},
|
|
3207
|
+
{
|
|
3208
|
+
...options.proxyUploadOptions,
|
|
3209
|
+
idempotencyKey,
|
|
3210
|
+
fetchImpl: (input, init) => paymentFetch(input, init)
|
|
3108
3211
|
}
|
|
3109
|
-
|
|
3110
|
-
|
|
3212
|
+
);
|
|
3213
|
+
await uploadPresignedObjectIfNeeded(
|
|
3214
|
+
uploadResponse,
|
|
3215
|
+
preparedPayload.payload.mode,
|
|
3216
|
+
preparedPayload.encryptedContent,
|
|
3217
|
+
fetchImpl
|
|
3218
|
+
);
|
|
3219
|
+
let finalizedUploadResponse = uploadResponse;
|
|
3220
|
+
if (preparedPayload.payload.mode === "presigned" && uploadResponse.confirmation_required === true) {
|
|
3111
3221
|
try {
|
|
3112
|
-
|
|
3113
|
-
parsed.uploadRequest.quote_id,
|
|
3114
|
-
objectLogHomeDir
|
|
3115
|
-
);
|
|
3116
|
-
if (!loggedQuote) {
|
|
3117
|
-
return {
|
|
3118
|
-
text: "Cannot upload storage object: quote-id not found in object.log. Run /mnemospark-cloud price-storage first.",
|
|
3119
|
-
isError: true
|
|
3120
|
-
};
|
|
3121
|
-
}
|
|
3122
|
-
if (loggedQuote.walletAddress.toLowerCase() !== parsed.uploadRequest.wallet_address.toLowerCase() || loggedQuote.objectId !== parsed.uploadRequest.object_id || loggedQuote.objectIdHash.toLowerCase() !== parsed.uploadRequest.object_id_hash.toLowerCase()) {
|
|
3123
|
-
return {
|
|
3124
|
-
text: "Cannot upload storage object: quote details do not match wallet/object arguments.",
|
|
3125
|
-
isError: true
|
|
3126
|
-
};
|
|
3127
|
-
}
|
|
3128
|
-
const archivePath = join5(
|
|
3129
|
-
options.backupOptions?.tmpDir ?? DEFAULT_BACKUP_DIR,
|
|
3130
|
-
parsed.uploadRequest.object_id
|
|
3131
|
-
);
|
|
3132
|
-
let archiveStats;
|
|
3133
|
-
try {
|
|
3134
|
-
archiveStats = await stat(archivePath);
|
|
3135
|
-
} catch {
|
|
3136
|
-
return {
|
|
3137
|
-
text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /mnemospark-cloud backup first.`,
|
|
3138
|
-
isError: true
|
|
3139
|
-
};
|
|
3140
|
-
}
|
|
3141
|
-
if (!archiveStats.isFile()) {
|
|
3142
|
-
return {
|
|
3143
|
-
text: `Cannot upload storage object: local archive path is not a file (${archivePath}).`,
|
|
3144
|
-
isError: true
|
|
3145
|
-
};
|
|
3146
|
-
}
|
|
3147
|
-
const archiveHash = await sha256File(archivePath);
|
|
3148
|
-
if (archiveHash.toLowerCase() !== parsed.uploadRequest.object_id_hash.toLowerCase()) {
|
|
3149
|
-
return {
|
|
3150
|
-
text: "Cannot upload storage object: object-id-hash does not match local archive.",
|
|
3151
|
-
isError: true
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
const walletKey = await resolveWalletKey(objectLogHomeDir);
|
|
3155
|
-
const walletAccount = privateKeyToAccount5(walletKey);
|
|
3156
|
-
if (walletAccount.address.toLowerCase() !== parsed.uploadRequest.wallet_address.toLowerCase()) {
|
|
3157
|
-
return {
|
|
3158
|
-
text: `Cannot upload storage object: wallet key address ${walletAccount.address} does not match --wallet-address ${parsed.uploadRequest.wallet_address}.`,
|
|
3159
|
-
isError: true
|
|
3160
|
-
};
|
|
3161
|
-
}
|
|
3162
|
-
const preparedPayload = await prepareUploadPayload(
|
|
3163
|
-
archivePath,
|
|
3164
|
-
parsed.uploadRequest.wallet_address,
|
|
3165
|
-
objectLogHomeDir
|
|
3166
|
-
);
|
|
3167
|
-
const paymentFetch = createPayment(walletKey).fetch;
|
|
3168
|
-
const idempotencyKey = idempotencyKeyFn();
|
|
3169
|
-
const uploadResponse = await requestStorageUpload(
|
|
3222
|
+
finalizedUploadResponse = await requestStorageUploadConfirm(
|
|
3170
3223
|
{
|
|
3171
|
-
quote_id:
|
|
3224
|
+
quote_id: uploadResponse.quote_id,
|
|
3172
3225
|
wallet_address: parsed.uploadRequest.wallet_address,
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
quoted_storage_price: loggedQuote.storagePrice,
|
|
3176
|
-
payload: preparedPayload.payload
|
|
3226
|
+
object_key: uploadResponse.object_key,
|
|
3227
|
+
idempotency_key: idempotencyKey
|
|
3177
3228
|
},
|
|
3178
|
-
|
|
3179
|
-
...options.proxyUploadOptions,
|
|
3180
|
-
idempotencyKey,
|
|
3181
|
-
fetchImpl: (input, init) => paymentFetch(input, init)
|
|
3182
|
-
}
|
|
3183
|
-
);
|
|
3184
|
-
await uploadPresignedObjectIfNeeded(
|
|
3185
|
-
uploadResponse,
|
|
3186
|
-
preparedPayload.payload.mode,
|
|
3187
|
-
preparedPayload.encryptedContent,
|
|
3188
|
-
fetchImpl
|
|
3229
|
+
options.proxyUploadConfirmOptions
|
|
3189
3230
|
);
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
quote_id: uploadResponse.quote_id,
|
|
3196
|
-
wallet_address: parsed.uploadRequest.wallet_address,
|
|
3197
|
-
object_key: uploadResponse.object_key,
|
|
3198
|
-
idempotency_key: idempotencyKey
|
|
3199
|
-
},
|
|
3200
|
-
options.proxyUploadConfirmOptions
|
|
3201
|
-
);
|
|
3202
|
-
} catch (confirmError) {
|
|
3203
|
-
const transId = uploadResponse.trans_id ?? "unknown";
|
|
3204
|
-
const confirmMessage = extractUploadErrorMessage(confirmError) ?? "Upload confirmation request failed";
|
|
3205
|
-
throw new Error(
|
|
3206
|
-
`Upload to S3 succeeded, but backend confirmation failed (trans_id: ${transId}, idempotency_key: ${idempotencyKey}). ${confirmMessage}`
|
|
3207
|
-
);
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
await appendStorageUploadLog(finalizedUploadResponse, objectLogHomeDir, nowDateFn);
|
|
3211
|
-
const cronStoragePriceCandidate = finalizedUploadResponse.storage_price ?? loggedQuote.storagePrice;
|
|
3212
|
-
const cronStoragePrice = Number.isFinite(cronStoragePriceCandidate) && cronStoragePriceCandidate > 0 ? cronStoragePriceCandidate : loggedQuote.storagePrice;
|
|
3213
|
-
const cronJob = await createStoragePaymentCronJob(
|
|
3214
|
-
finalizedUploadResponse,
|
|
3215
|
-
cronStoragePrice,
|
|
3216
|
-
objectLogHomeDir,
|
|
3217
|
-
nowDateFn
|
|
3231
|
+
} catch (confirmError) {
|
|
3232
|
+
const transId = uploadResponse.trans_id ?? "unknown";
|
|
3233
|
+
const confirmMessage = extractUploadErrorMessage(confirmError) ?? "Upload confirmation request failed";
|
|
3234
|
+
throw new Error(
|
|
3235
|
+
`Upload to S3 succeeded, but backend confirmation failed (trans_id: ${transId}, idempotency_key: ${idempotencyKey}). ${confirmMessage}`
|
|
3218
3236
|
);
|
|
3219
|
-
await maybeCleanupLocalBackupArchive(archivePath);
|
|
3220
|
-
return {
|
|
3221
|
-
text: formatStorageUploadUserMessage(finalizedUploadResponse, cronJob.cronId)
|
|
3222
|
-
};
|
|
3223
|
-
} catch (error) {
|
|
3224
|
-
const uploadErrorMessage = extractUploadErrorMessage(error);
|
|
3225
|
-
return {
|
|
3226
|
-
text: uploadErrorMessage ?? "Cannot upload storage object",
|
|
3227
|
-
isError: true
|
|
3228
|
-
};
|
|
3229
3237
|
}
|
|
3230
3238
|
}
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3239
|
+
await appendStorageUploadLog(finalizedUploadResponse, objectLogHomeDir, nowDateFn);
|
|
3240
|
+
const cronStoragePriceCandidate = finalizedUploadResponse.storage_price ?? loggedQuote.storagePrice;
|
|
3241
|
+
const cronStoragePrice = Number.isFinite(cronStoragePriceCandidate) && cronStoragePriceCandidate > 0 ? cronStoragePriceCandidate : loggedQuote.storagePrice;
|
|
3242
|
+
const cronJob = await createStoragePaymentCronJob(
|
|
3243
|
+
finalizedUploadResponse,
|
|
3244
|
+
cronStoragePrice,
|
|
3245
|
+
objectLogHomeDir,
|
|
3246
|
+
nowDateFn
|
|
3247
|
+
);
|
|
3248
|
+
await maybeCleanupLocalBackupArchive(archivePath);
|
|
3249
|
+
return {
|
|
3250
|
+
text: formatStorageUploadUserMessage(finalizedUploadResponse, cronJob.cronId)
|
|
3251
|
+
};
|
|
3252
|
+
} catch (error) {
|
|
3253
|
+
const uploadErrorMessage = extractUploadErrorMessage(error);
|
|
3254
|
+
return {
|
|
3255
|
+
text: uploadErrorMessage ?? "Cannot upload storage object",
|
|
3256
|
+
isError: true
|
|
3257
|
+
};
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3260
|
+
if (parsed.mode === "ls") {
|
|
3261
|
+
try {
|
|
3262
|
+
const lsResult = await requestStorageLs(
|
|
3263
|
+
parsed.storageObjectRequest,
|
|
3264
|
+
options.proxyStorageOptions
|
|
3265
|
+
);
|
|
3266
|
+
if (!lsResult.success) {
|
|
3267
|
+
throw new Error("ls failed");
|
|
3249
3268
|
}
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3269
|
+
return {
|
|
3270
|
+
text: formatStorageLsUserMessage(lsResult, parsed.storageObjectRequest.object_key)
|
|
3271
|
+
};
|
|
3272
|
+
} catch {
|
|
3273
|
+
return {
|
|
3274
|
+
text: "Cannot list storage object",
|
|
3275
|
+
isError: true
|
|
3276
|
+
};
|
|
3277
|
+
}
|
|
3278
|
+
}
|
|
3279
|
+
if (parsed.mode === "download") {
|
|
3280
|
+
try {
|
|
3281
|
+
const downloadResult = await requestStorageDownload(
|
|
3282
|
+
parsed.storageObjectRequest,
|
|
3283
|
+
options.proxyStorageOptions
|
|
3284
|
+
);
|
|
3285
|
+
if (!downloadResult.success) {
|
|
3286
|
+
throw new Error("download failed");
|
|
3268
3287
|
}
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
cronEntry = await findLoggedStoragePaymentCronByObjectKey(
|
|
3288
|
-
parsed.storageObjectRequest.object_key,
|
|
3289
|
-
objectLogHomeDir
|
|
3290
|
-
);
|
|
3291
|
-
cronDeleted = cronEntry ? await removeStoragePaymentCronJob(cronEntry.cronId, objectLogHomeDir) : false;
|
|
3292
|
-
} catch {
|
|
3293
|
-
}
|
|
3294
|
-
return {
|
|
3295
|
-
text: formatStorageDeleteUserMessage(
|
|
3296
|
-
parsed.storageObjectRequest.object_key,
|
|
3297
|
-
cronEntry?.cronId ?? null,
|
|
3298
|
-
cronDeleted
|
|
3299
|
-
)
|
|
3300
|
-
};
|
|
3288
|
+
return {
|
|
3289
|
+
text: `File ${parsed.storageObjectRequest.object_key} downloaded to ${downloadResult.file_path}`
|
|
3290
|
+
};
|
|
3291
|
+
} catch {
|
|
3292
|
+
return {
|
|
3293
|
+
text: "Cannot download file",
|
|
3294
|
+
isError: true
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
if (parsed.mode === "delete") {
|
|
3299
|
+
try {
|
|
3300
|
+
const deleteResult = await requestStorageDelete(
|
|
3301
|
+
parsed.storageObjectRequest,
|
|
3302
|
+
options.proxyStorageOptions
|
|
3303
|
+
);
|
|
3304
|
+
if (!deleteResult.success) {
|
|
3305
|
+
throw new Error("delete failed");
|
|
3301
3306
|
}
|
|
3307
|
+
} catch {
|
|
3302
3308
|
return {
|
|
3303
|
-
text:
|
|
3309
|
+
text: "Cannot delete file",
|
|
3304
3310
|
isError: true
|
|
3305
3311
|
};
|
|
3306
3312
|
}
|
|
3313
|
+
let cronEntry = null;
|
|
3314
|
+
let cronDeleted = false;
|
|
3315
|
+
try {
|
|
3316
|
+
cronEntry = await findLoggedStoragePaymentCronByObjectKey(
|
|
3317
|
+
parsed.storageObjectRequest.object_key,
|
|
3318
|
+
objectLogHomeDir
|
|
3319
|
+
);
|
|
3320
|
+
cronDeleted = cronEntry ? await removeStoragePaymentCronJob(cronEntry.cronId, objectLogHomeDir) : false;
|
|
3321
|
+
} catch {
|
|
3322
|
+
}
|
|
3323
|
+
return {
|
|
3324
|
+
text: formatStorageDeleteUserMessage(
|
|
3325
|
+
parsed.storageObjectRequest.object_key,
|
|
3326
|
+
cronEntry?.cronId ?? null,
|
|
3327
|
+
cronDeleted
|
|
3328
|
+
)
|
|
3329
|
+
};
|
|
3330
|
+
}
|
|
3331
|
+
return {
|
|
3332
|
+
text: CLOUD_HELP_TEXT,
|
|
3333
|
+
isError: true
|
|
3307
3334
|
};
|
|
3308
3335
|
}
|
|
3309
3336
|
|