Files
Oleg Isonen 82c3d83fd1 fix: optimize CLI import for large data amount (#5831)
## Summary

- Add CLI project import support from synced `.webstudio/data.json` into
another project via a destination share link.
- Move project bundle import/export contract into
`@webstudio-is/protocol`, including bundle versioning, staged upload
constants, schema validation, and fixture coverage.
- Upload project bundle data through staged TUS upload before calling
the import RPC to avoid request body limits.
- Upload referenced assets as binary files through the existing asset
upload route before importing asset rows.
- Add `--skip-assets` and `--ignore-version-check` import options.
- Add retry handling for transient missing imported asset files by
re-uploading only the reported missing assets.
- Share missing-asset import error formatting/parsing through protocol
to avoid duplicated string contracts.
- Preserve browser asset upload behavior while adding API upload
support.
- Normalize schema naming across the branch to lower-case names without
`Schema` suffix.
2026-06-23 18:50:01 +02:00

74 lines
1.7 KiB
TypeScript

import { isRouteErrorResponse } from "@remix-run/react";
import { z } from "zod";
// Currently, we have multiple error formats, and not all of them are covered here.
// We should consolidate these formats into a single, unified format for consistency.
const pageError = z.union([
z.string().transform((message) => ({ message, description: undefined })),
z
.object({
message: z.string(),
details: z.string(),
hint: z.string().nullable(),
code: z.string(),
})
.transform(({ message, details, hint, code }) => ({
message,
description: `details: ${details}; hint: ${hint}; code: ${code}`,
})),
z.object({
message: z.string(),
description: z.string().optional(),
}),
]);
export const parseError = (
error: unknown
): {
status: number;
statusText?: string;
message: string;
description?: string;
} => {
if (error instanceof Error) {
return {
message: error.message,
status: 500,
};
}
if (isRouteErrorResponse(error)) {
const parsed = pageError.safeParse(error.data);
if (parsed.success) {
return {
message: parsed.data.message,
description: parsed.data.description,
status: error.status,
statusText: error.statusText,
};
}
return {
message: error.data ? JSON.stringify(error.data) : "unknown error",
status: error.status,
statusText: error.statusText,
};
}
const parsed = pageError.safeParse(error);
if (parsed.success) {
return {
message: parsed.data.message,
description: parsed.data.description,
status: 1001,
};
}
return {
message: JSON.stringify(error ?? "unknown error"),
status: 1001,
statusText: undefined,
};
};