mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-07 20:44:05 +09:00
fix UserProp schema
This commit is contained in:
1 parent
a50913d9cc
commit
26f0990347
25 files changed
+85
-88
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { renderHook, act } from "@testing-library/react-hooks";
|
||||
import { type ComponentName, UserProp } from "@webstudio-is/react-sdk";
|
||||
import type { ComponentName, UserProp } from "@webstudio-is/react-sdk";
|
||||
import { nanoid } from "nanoid";
|
||||
import type { SelectedInstanceData } from "@webstudio-is/project";
|
||||
import { usePropsLogic } from "./use-props-logic";
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Instance, UserUserProp } from "@webstudio-is/react-sdk";
|
||||
import { Instance, UserProps } from "@webstudio-is/react-sdk";
|
||||
import { z } from "zod";
|
||||
|
||||
const TYPE = "@webstudio/instance/v0.1" as const;
|
||||
|
||||
const InstanceCopyData = z.object({
|
||||
instance: Instance,
|
||||
props: z.array(UserUserProp).optional(),
|
||||
props: UserProps.optional(),
|
||||
});
|
||||
|
||||
export type InstanceCopyData = z.infer<typeof InstanceCopyData>;
|
||||
|
||||
@@ -21,4 +21,5 @@ module.exports = {
|
||||
moduleNameMapper: {
|
||||
"^~/(.*)$": "<rootDir>/app/$1",
|
||||
},
|
||||
// extensionsToTreatAsEsm: [".ts", ".tsx"],
|
||||
};
|
||||
@@ -29,7 +29,7 @@
|
||||
"@webstudio-is/jest-config": "*",
|
||||
"tsup": "^6.1.3",
|
||||
"typescript": "4.7.4",
|
||||
"zod": "^3.17.3"
|
||||
"zod": "^3.19.1"
|
||||
},
|
||||
"exports": {
|
||||
".": "./lib/index.js",
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { type FontMeta } from "@webstudio-is/fonts/server";
|
||||
import { type FontMeta } from "@webstudio-is/fonts";
|
||||
import {
|
||||
prisma,
|
||||
type Location,
|
||||
type Project,
|
||||
} from "@webstudio-is/prisma-client";
|
||||
import { formatAsset, type ImageMeta } from "../utils/format-asset";
|
||||
import { type ImageMeta } from "../schema";
|
||||
import { formatAsset } from "../utils/format-asset";
|
||||
|
||||
type BaseOptions = {
|
||||
name: string;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { prisma } from "@webstudio-is/prisma-client";
|
||||
import { Asset } from "../types";
|
||||
import { Asset } from "../schema";
|
||||
|
||||
export const deleteFromDb = async (ids: Array<Asset["id"]>) => {
|
||||
if (ids.length === 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { prisma, Project } from "@webstudio-is/prisma-client";
|
||||
import { Asset } from "../types";
|
||||
import { Asset } from "../schema";
|
||||
import { formatAsset } from "../utils/format-asset";
|
||||
|
||||
export const loadByProject = async (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { prisma } from "@webstudio-is/prisma-client";
|
||||
import { deleteFromDb } from "./db";
|
||||
import { Asset } from "./types";
|
||||
import { Asset } from "./schema";
|
||||
import { deleteFromFs } from "./targets/fs/delete";
|
||||
import { deleteFromS3 } from "./targets/s3/delete";
|
||||
import { formatAsset } from "./utils/format-asset";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from "./types";
|
||||
export * from "./schema";
|
||||
export * from "./constants";
|
||||
export * from "./utils/filter-by-type";
|
||||
export * from "./utils/to-bytes";
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { z } from "zod";
|
||||
import { FontFormat, FontMeta } from "@webstudio-is/fonts";
|
||||
import { DEFAULT_UPLOAD_PATH, MAX_UPLOAD_SIZE } from "./constants";
|
||||
import { toBytes } from "./utils/to-bytes";
|
||||
|
||||
export const ImageMeta = z.object({
|
||||
width: z.number(),
|
||||
height: z.number(),
|
||||
});
|
||||
export type ImageMeta = z.infer<typeof ImageMeta>;
|
||||
|
||||
const maxSize = z
|
||||
.string()
|
||||
// user inputs the max value in mb and we transform it to bytes
|
||||
@@ -23,3 +30,32 @@ export const FsEnv = z.object({
|
||||
MAX_UPLOAD_SIZE: maxSize,
|
||||
FILE_UPLOAD_PATH: z.string().default(DEFAULT_UPLOAD_PATH),
|
||||
});
|
||||
|
||||
const Location = z.union([z.literal("FS"), z.literal("REMOTE")]);
|
||||
|
||||
const BaseAsset = z.object({
|
||||
id: z.string(),
|
||||
projectId: z.string(),
|
||||
format: z.string(),
|
||||
size: z.number(),
|
||||
name: z.string(),
|
||||
description: z.union([z.string(), z.null()]),
|
||||
location: Location,
|
||||
createdAt: z.string(),
|
||||
path: z.string(),
|
||||
status: z.literal("uploaded").optional(),
|
||||
});
|
||||
|
||||
export const FontAsset = BaseAsset.omit({ format: true }).extend({
|
||||
format: FontFormat,
|
||||
meta: FontMeta,
|
||||
});
|
||||
export type FontAsset = z.infer<typeof FontAsset>;
|
||||
|
||||
export const ImageAsset = BaseAsset.extend({
|
||||
meta: ImageMeta,
|
||||
});
|
||||
export type ImageAsset = z.infer<typeof ImageAsset>;
|
||||
|
||||
export const Asset = z.union([FontAsset, ImageAsset]);
|
||||
export type Asset = z.infer<typeof Asset>;
|
||||
@@ -8,7 +8,7 @@ import { Location } from "@webstudio-is/prisma-client";
|
||||
import { getAssetData } from "../../utils/get-asset-data";
|
||||
import { createMany } from "../../db";
|
||||
import { FILE_DIRECTORY } from "./file-path";
|
||||
import { Asset } from "../../types";
|
||||
import { Asset } from "../../schema";
|
||||
import { getUniqueFilename } from "../../utils/get-unique-filename";
|
||||
import { sanitizeS3Key } from "../../utils/sanitize-s3-key";
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { S3Env } from "../../schema";
|
||||
import { toUint8Array } from "../../utils/to-uint8-array";
|
||||
import { getAssetData } from "../../utils/get-asset-data";
|
||||
import { createMany } from "../../db";
|
||||
import type { Asset } from "../../types";
|
||||
import type { Asset } from "../../schema";
|
||||
import { getUniqueFilename } from "../../utils/get-unique-filename";
|
||||
import { getS3Client } from "./client";
|
||||
import { sanitizeS3Key } from "../../utils/sanitize-s3-key";
|
||||
|
||||
@@ -1,23 +1 @@
|
||||
import type { FontFormat } from "@webstudio-is/fonts";
|
||||
import type { FontMeta } from "@webstudio-is/fonts/server";
|
||||
import { Asset as DbAsset } from "@webstudio-is/prisma-client";
|
||||
import type { ImageMeta } from "./utils/format-asset";
|
||||
|
||||
type BaseAsset = Omit<DbAsset, "meta" | "createdAt"> & {
|
||||
path: string;
|
||||
status?: "uploaded";
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export type FontAsset = Omit<BaseAsset, "format"> & {
|
||||
format: FontFormat;
|
||||
meta: FontMeta;
|
||||
};
|
||||
|
||||
export type ImageAsset = BaseAsset & {
|
||||
meta: ImageMeta;
|
||||
};
|
||||
|
||||
export type Asset = FontAsset | ImageAsset;
|
||||
|
||||
export type AssetType = "image" | "font";
|
||||
@@ -1,15 +1,8 @@
|
||||
import { z } from "zod";
|
||||
import type { Asset as DbAsset } from "@webstudio-is/prisma-client";
|
||||
import { type FontFormat, FONT_FORMATS } from "@webstudio-is/fonts";
|
||||
import { FontMeta } from "@webstudio-is/fonts/server";
|
||||
import type { Asset } from "../types";
|
||||
import { FontMeta } from "@webstudio-is/fonts";
|
||||
import { getAssetPath } from "./get-asset-path";
|
||||
|
||||
const ImageMeta = z.object({
|
||||
width: z.number(),
|
||||
height: z.number(),
|
||||
});
|
||||
export type ImageMeta = z.infer<typeof ImageMeta>;
|
||||
import { type Asset, ImageMeta } from "../schema";
|
||||
|
||||
export const formatAsset = (asset: DbAsset): Asset => {
|
||||
const base = { ...asset, path: getAssetPath(asset) };
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Location } from "@webstudio-is/prisma-client";
|
||||
import sharp from "sharp";
|
||||
import { ImageMeta } from "./format-asset";
|
||||
import { type FontMeta, getFontData } from "@webstudio-is/fonts/server";
|
||||
import { type ImageMeta } from "../schema";
|
||||
import { type FontMeta } from "@webstudio-is/fonts";
|
||||
import { getFontData } from "@webstudio-is/fonts/server";
|
||||
|
||||
type BaseData = {
|
||||
name: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { FontFormat } from "./types";
|
||||
import type { FontFormat } from "./schema";
|
||||
|
||||
export const SYSTEM_FONTS = new Map([
|
||||
["Arial", ["sans-serif"]],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { FontFormat } from "./types";
|
||||
import type { FontFormat } from "./schema";
|
||||
import { create as createFontKit } from "fontkit";
|
||||
import { FontWeight, fontWeights } from "./font-weights";
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { FONT_FORMATS } from "./constants";
|
||||
import type { FontMeta } from "./schema";
|
||||
import type { FontFormat } from "./types";
|
||||
import type { FontMeta, FontFormat } from "./schema";
|
||||
|
||||
export type PartialFontAsset = {
|
||||
format: FontFormat;
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export { getFontData } from "./font-data";
|
||||
export * from "./schema";
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from "./constants";
|
||||
export * from "./get-font-faces";
|
||||
export * from "./types";
|
||||
export * from "./schema";
|
||||
export * from "./font-weights";
|
||||
@@ -1,6 +1,14 @@
|
||||
import { z } from "zod";
|
||||
import { styles } from "./font-data";
|
||||
|
||||
export const FontFormat = z.union([
|
||||
z.literal("ttf"),
|
||||
z.literal("woff"),
|
||||
z.literal("woff2"),
|
||||
z.literal("otf"),
|
||||
]);
|
||||
export type FontFormat = z.infer<typeof FontFormat>;
|
||||
|
||||
export const FontMeta = z.object({
|
||||
family: z.string(),
|
||||
style: z.enum(styles),
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export type FontFormat = "ttf" | "woff" | "woff2" | "otf";
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
type AllUserProps,
|
||||
type UserProp,
|
||||
// @todo move zod schema into project package
|
||||
UserUserProps,
|
||||
UserProps,
|
||||
UserDbProps,
|
||||
} from "@webstudio-is/react-sdk";
|
||||
import { applyPatches, type Patch } from "immer";
|
||||
@@ -124,7 +124,10 @@ export const patch = async (
|
||||
|
||||
await Promise.all(
|
||||
Object.values(nextProps).map(({ id, instanceId, treeId, props }) => {
|
||||
const propsDb = UserUserProps.parse(props);
|
||||
const propsDb: UserDbProps = UserProps.parse(props).map((prop) => {
|
||||
const { asset, ...rest } = prop;
|
||||
return { ...rest, assetId: asset?.id };
|
||||
});
|
||||
|
||||
const propsString = JSON.stringify(propsDb);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import type { Asset } from "@webstudio-is/asset-uploader";
|
||||
import { Asset } from "@webstudio-is/asset-uploader";
|
||||
|
||||
const UserPropDb = z.object({
|
||||
id: z.string(),
|
||||
@@ -8,36 +8,19 @@ const UserPropDb = z.object({
|
||||
assetId: z.optional(z.string()),
|
||||
required: z.optional(z.boolean()),
|
||||
});
|
||||
export type UserPropDb = z.infer<typeof UserPropDb>;
|
||||
|
||||
export const UserDbProps = z.array(UserPropDb);
|
||||
export type UserDbProps = z.infer<typeof UserDbProps>;
|
||||
|
||||
export const UserUserProp = z
|
||||
.object({
|
||||
id: z.string(),
|
||||
prop: z.string(),
|
||||
value: z.union([z.string(), z.boolean()]),
|
||||
// We are not interested in Props data does any other props on asset exists
|
||||
asset: z.optional(z.object({ id: z.string() })),
|
||||
required: z.optional(z.boolean()),
|
||||
})
|
||||
.transform(({ id, prop, value, asset, required }) => {
|
||||
// Check with infer that we are transforming to UserPropDb
|
||||
const res: z.infer<typeof UserPropDb> = {
|
||||
id,
|
||||
prop,
|
||||
value,
|
||||
assetId: asset?.id,
|
||||
required,
|
||||
};
|
||||
return res;
|
||||
});
|
||||
export const UserProp = z.object({
|
||||
id: z.string(),
|
||||
prop: z.string(),
|
||||
value: z.union([z.string(), z.boolean()]),
|
||||
asset: Asset.optional(),
|
||||
required: z.optional(z.boolean()),
|
||||
});
|
||||
export type UserProp = z.infer<typeof UserProp>;
|
||||
|
||||
export const UserUserProps = z.array(UserUserProp);
|
||||
|
||||
export type UserProp = {
|
||||
id: string;
|
||||
prop: string;
|
||||
value: string | boolean;
|
||||
asset?: Asset;
|
||||
required?: boolean | undefined;
|
||||
};
|
||||
export const UserProps = z.array(UserProp);
|
||||
export type UserProps = z.infer<typeof UserProps>;
|
||||
@@ -18600,11 +18600,6 @@ zod-form-data@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/zod-form-data/-/zod-form-data-1.2.1.tgz#6da07d7964765b464e959a75f0d797690ee477f7"
|
||||
integrity sha512-L4zocmlzikYB9A2uVVj3OUKX/t3spOZTzQLOhoCXECn9w+eN3bw0D/KYGX4J72iLdCIwDP6YJyYwVXkx3WTu7A==
|
||||
|
||||
zod@^3.17.3:
|
||||
version "3.17.3"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.17.3.tgz#86abbc670ff0063a4588d85a4dcc917d6e4af2ba"
|
||||
integrity sha512-4oKP5zvG6GGbMlqBkI5FESOAweldEhSOZ6LI6cG+JzUT7ofj1ZOC0PJudpQOpT1iqOFpYYtX5Pw0+o403y4bcg==
|
||||
|
||||
zod@^3.19.1:
|
||||
version "3.19.1"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.19.1.tgz#112f074a97b50bfc4772d4ad1576814bd8ac4473"
|
||||
|
||||
Reference in new issue
Block a user