Skip to content

Commit

Permalink
refactor(formily-schema,zod): 💅 refactor zod, formily-schema by TypeR…
Browse files Browse the repository at this point in the history
…esolver

and teset update by snapshots
  • Loading branch information
charlzyx committed Dec 16, 2024
1 parent abf7eb6 commit aab9b8e
Show file tree
Hide file tree
Showing 13 changed files with 455 additions and 482 deletions.
Binary file modified bun.lockb
Binary file not shown.
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@
},
"scripts": {
"build": "npm run clean && turbo run build",
"changelog": "turbo run changelog -- ",
"clean": "rm -rf packages/**/dist"
},
"dependencies": {
"@clack/prompts": "^0.8.2",
"ts-morph": "^24.0.0",
"typescript": "^5.7.2"
},
"devDependencies": {
"@inquirer/prompts": "^7.2.0",
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-typescript": "^11.0.0",
Expand Down
31 changes: 31 additions & 0 deletions packages/core/__tests__/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`removeEmptyComments 应该移除空注释 / should remove empty comments from the input string 1`] = `"another comment"`;

exports[`removeEmptyComments 当没有空注释时应返回原字符串 / should return the original string if no empty comments are present 1`] = `"another comment"`;

exports[`removeEmptyComments 应该移除多行注释中的空行 / should remove empty lines in multi-line comments 1`] = `
"这是一段描述
another comment"
`;

exports[`removeEmptyComments 应该移除单行注释 / should remove single line comments 1`] = `"这是一个注释"`;

exports[`removeEmptyComments 应该处理没有注释的情况 / should handle cases with no comments 1`] = `""`;

exports[`parseAndRemoveAnnotations 应该解析注解并从输入字符串中移除它们 / should parse annotations and remove them from the input string 1`] = `
{
"cleaned": "some text",
"parsed": {
"flag": true,
"title": "Example",
},
}
`;

exports[`parseAndRemoveAnnotations 当没有注解时应返回空的解析对象和清理后的字符串 / should return empty parsed object and cleaned string if no annotations are present 1`] = `
{
"cleaned": "some text without annotations",
"parsed": {},
}
`;
20 changes: 7 additions & 13 deletions packages/core/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ describe("removeEmptyComments", () => {
// another comment
`;
const result = removeEmptyComments(input.trim());
expect(result).toBe("another comment");
expect(result).toMatchSnapshot();
});

it("当没有空注释时应返回原字符串 / should return the original string if no empty comments are present", () => {
const input = `
// another comment
`;
const result = removeEmptyComments(input.trim());
expect(result).toBe("another comment");
expect(result).toMatchSnapshot();
});

it("应该移除多行注释中的空行 / should remove empty lines in multi-line comments", () => {
Expand All @@ -36,40 +36,34 @@ describe("removeEmptyComments", () => {
// another comment
`;
const result = removeEmptyComments(input.trim());
expect(result).toBe("这是一段描述\nanother comment");
expect(result).toMatchSnapshot();
});

it("应该移除单行注释 / should remove single line comments", () => {
const input = `
// 这是一个注释
`;
const result = removeEmptyComments(input.trim());
expect(result).toBe("这是一个注释");
expect(result).toMatchSnapshot();
});

it("应该处理没有注释的情况 / should handle cases with no comments", () => {
const input = ``;
const result = removeEmptyComments(input.trim());
expect(result).toBe("");
expect(result).toMatchSnapshot();
});
});

describe("parseAndRemoveAnnotations", () => {
it("应该解析注解并从输入字符串中移除它们 / should parse annotations and remove them from the input string", () => {
const input = "@title(Example) some text @flag";
const result = parseAndRemoveAnnotations(input);
expect(result).toEqual({
parsed: { title: "Example", flag: true },
cleaned: "some text",
});
expect(result).toMatchSnapshot();
});

it("当没有注解时应返回空的解析对象和清理后的字符串 / should return empty parsed object and cleaned string if no annotations are present", () => {
const input = "some text without annotations";
const result = parseAndRemoveAnnotations(input);
expect(result).toEqual({
parsed: {},
cleaned: input,
});
expect(result).toMatchSnapshot();
});
});
119 changes: 119 additions & 0 deletions packages/formily-schema/__tests__/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`formily schema tests 应该正确转换用户信息模式 / should transform user information schema correctly 1`] = `
"import { ISchema } from "@formily/json-schema";
const Form: ISchema = {
"type": "object",
"properties": {
"user": User
}
};
const User: ISchema = {
"type": "object",
"properties": {
"name": {
"x-decorator": "FormItem",
"x-component": "Input",
"title": "用户名",
"type": "string"
},
"address": Address,
"addressList": {
"description": "地址列表",
"type": "array",
"x-component": "ArrayTable",
"items": {
"type": "void",
"x-component": "ArrayTable.Item",
"properties": "#Address"
}
}
}
};
const Address: ISchema = {
"type": "object",
"properties": {
"city": {
"x-decorator": "FormItem",
"x-component": "Input",
"title": "城市",
"enum": [
{
"label": "北京",
"value": "北京"
},
{
"label": "上海",
"value": "上海"
}
]
},
"street": {
"x-decorator": "FormItem",
"x-component": "Input",
"title": "街道",
"type": "string"
}
}
};
"
`;

exports[`formily schema tests 应该处理循环引用 / should handle circular references 1`] = `
"import { ISchema } from "@formily/json-schema";
const Form: ISchema = {
"type": "object",
"properties": {
"a": A
}
};
const A: ISchema = {
"type": "object",
"properties": {
"b": B
}
};
const B: ISchema = {
"type": "object",
"properties": {
"a": A
}
};
"
`;

exports[`formily schema tests 应该正确转换基本类型 / should transform basic types correctly 1`] = `
"import { ISchema } from "@formily/json-schema";
const Form: ISchema = {
"type": "object",
"properties": {
"basicTypes": BasicTypes
}
};
const BasicTypes: ISchema = {
"type": "object",
"properties": {
"str": {
"x-decorator": "FormItem",
"x-component": "Input",
"type": "string"
},
"num": {
"x-decorator": "FormItem",
"x-component": "Input",
"type": "number"
},
"bool": {
"x-decorator": "FormItem",
"x-component": "Input",
"type": "boolean"
}
}
};
"
`;
83 changes: 11 additions & 72 deletions packages/formily-schema/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ describe("formily schema tests", () => {
name: string;
/** 地址信息 */
address: Address;
/** 地址列表 */
addressList: Address[]
}
class Address {
Expand All @@ -31,41 +33,10 @@ describe("formily schema tests", () => {
`
);

const schema = transform(project);
expect(schema).toEqual({
properties: {
user: {
comment: "#User",
properties: {
address: {
comment: "#Address",
properties: {
city: {
title: "城市",
enum: [
{ label: "北京", value: "北京" },
{ label: "上海", value: "上海" },
],
},
street: {
title: "街道",
type: "string",
},
},
type: "object",
},
name: {
title: "用户名",
type: "string",
},
},
type: "object",
},
},
type: "object",
});
const result = transform(project);
expect(result).toMatchSnapshot();

project.removeSourceFile(sourceFile); // 删除虚拟文件
project.removeSourceFile(sourceFile);
});

it("应该跳过被忽略的节点 / should skip ignored nodes", () => {
Expand Down Expand Up @@ -116,29 +87,10 @@ class B {
`
);

const schema = transform(project);
expect(schema).toEqual({
type: "object",
properties: {
a: {
type: "object",
properties: {
b: {
type: "object",
properties: {
a: {
$ref: "#CircleRef#A",
},
},
comment: "#B",
},
},
comment: "#A",
},
},
});
const result = transform(project);

project.removeSourceFile(sourceFile); // 删除虚拟文件
expect(result).toMatchSnapshot();
project.removeSourceFile(sourceFile);
});

it("应该正确转换基本类型 / should transform basic types correctly", () => {
Expand All @@ -157,22 +109,9 @@ class B {
`
);

const schema = transform(project);
expect(schema).toEqual({
properties: {
basicTypes: {
comment: "#BasicTypes",
type: "object",
properties: {
str: { type: "string" },
num: { type: "number" },
bool: { type: "boolean" },
},
},
},
type: "object",
});
const result = transform(project);

project.removeSourceFile(sourceFile); // 删除虚拟文件
expect(result).toMatchSnapshot();
project.removeSourceFile(sourceFile);
});
});
32 changes: 15 additions & 17 deletions packages/formily-schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import { Project } from "ts-morph";
import { transformDefinitions, SCHEMA_REF_PREFIX } from "./transformer";
import { transformDefinitions } from "./transformer";
import { getEntryNodes } from "./entry";
import { ISchema } from "@formily/json-schema";

const resolveRefs = (schema: ISchema) => {
const seen = new Map();

const clean = (schema: ISchema) => {
const replacer = (k: string, v: any) => {
if (k === "x-code") return undefined;
let ref = typeof v === "object" ? v["$ref"] : null;
if (!ref) return v;

if (seen.has(ref)) {
return { $ref: "#CircleRef" + ref };
} else if (ref) {
const link = schema[ref.replace(SCHEMA_REF_PREFIX, "")];
link.comment = ref;
seen.set(ref, link);
return link;
}
return v;
};

return JSON.parse(JSON.stringify(schema, replacer));
Expand All @@ -27,6 +15,16 @@ const resolveRefs = (schema: ISchema) => {
export const transform = (project: Project) => {
const { definitions } = getEntryNodes(project);
const schema = transformDefinitions(definitions);
const resolved = resolveRefs(schema);
return resolved["Form"];
const schemaDefs = clean(schema);
const prefix = 'import { ISchema } from "@formily/json-schema";';
const reforamt = Object.keys(schemaDefs).map((def) => {
return `const ${def}: ISchema = ${JSON.stringify(
schemaDefs[def],
null,
2
)};\n`.replace(/"#\w+"/, (m) => {
return m.replace(/"/g, "").replace("#", "");
});
});
return [prefix, ...reforamt].join("\n");
};
Loading

0 comments on commit aab9b8e

Please sign in to comment.