@scenemesh/entity-engine
Version:
一个“元数据驱动 + 组件适配 + 动态关系 + 视图管线”式的实体引擎。以 **Model + View + FieldType + SuiteAdapter + DataSource** 为五大支点,统一 CRUD / 查询 / 引用管理 / 视图渲染 / 扩展注册,支持在运行期无侵入拼装出 **表单、网格、主从、看板、仪表盘、流程/树形视图** 等多形态界面。
1 lines • 13.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/types/view.types.ts","../src/modules/build-in/views/auth/auth-view-comp.tsx","../src/modules/build-in/views/auth/auth.view.tsx"],"sourcesContent":["import type { ZodTypeAny } from 'zod';\nimport type { IEntityObject, EntityCSSProperties } from '../../types';\nimport type {\n IEntityViewDelegate,\n IEntityModelDelegate,\n IEntityViewFieldDelegate,\n} from '../../core';\n\nexport type EntityViewBehaviorMode = 'display' | 'edit';\n\nexport type EntityViewBehaviorType = {\n mode?: EntityViewBehaviorMode;\n readonly?: boolean;\n disableEdit?: boolean;\n disableDelete?: boolean;\n disableNew?: boolean;\n toCreating?: boolean;\n toCreatingId?: string;\n};\n\nexport type EntityViewCallbacksType = {\n onObjectDeleted?: (obj: IEntityObject) => void;\n onObjectCreated?: (obj: IEntityObject) => void;\n onObjectUpdated?: (obj: IEntityObject) => void;\n};\n\nexport type EntityViewReferenceType = {\n fromModelName: string;\n fromFieldName: string;\n fromObjectId: string;\n toModelName: string;\n};\n\nexport type EntityViewProps = {\n model: IEntityModelDelegate;\n viewData: IEntityViewDelegate;\n baseObjectId?: string;\n reference?: EntityViewReferenceType;\n behavior: EntityViewBehaviorType;\n callbacks?: EntityViewCallbacksType;\n};\n\nexport interface IEntityViewMetaInfo {\n viewName: string;\n displayName: string;\n icon?: string;\n description?: string;\n}\n\nexport abstract class EntityView<P extends EntityViewProps = EntityViewProps> {\n abstract readonly info: IEntityViewMetaInfo;\n\n abstract readonly Component: React.FC<P>;\n}\n\n/**\n * 封装由表单控制库(如 react-hook-form)注入的属性\n * @template TValue - 字段值的类型\n */\nexport type EntityWidgetFieldControlProps<TValue = any> = {\n name: string;\n value: TValue;\n onChange: (...event: any[]) => void;\n onBlur: () => void;\n ref: React.Ref<any>;\n};\n\n/**\n * 封装由表单控制库注入的字段状态\n */\nexport type EntityWidgetFieldState = {\n invalid: boolean;\n isTouched: boolean;\n isDirty: boolean;\n error?: {\n type: string;\n message?: string;\n };\n};\n\nexport type EntityWidgetProps = {\n object?: IEntityObject;\n value: any;\n model: IEntityModelDelegate;\n view: IEntityViewDelegate;\n field: IEntityViewFieldDelegate;\n behavior: EntityViewBehaviorType;\n hasReference?: boolean;\n reference?: {\n referenceModel: IEntityModelDelegate;\n objectNum: number;\n object?: IEntityObject;\n };\n maintain?: EntityViewBehaviorType;\n options?: {\n [key: string]: any;\n };\n sx?: React.CSSProperties;\n\n fieldControl?: EntityWidgetFieldControlProps;\n fieldState?: EntityWidgetFieldState;\n style?: EntityCSSProperties;\n className?: string;\n};\n\nexport interface IEntityWidgetMetaInfo {\n widgetName: string;\n displayName: string;\n icon?: string;\n description?: string;\n}\n\nexport type EntityViewCapabilityDescriptor = {\n operators: Array<{\n name: string; // 如: record.getValues / record.setValue / collection.query / board.moveCard\n category?: string; // record | collection | board | action | custom\n inputSchema?: ZodTypeAny; // 可选 Zod -> JSON Schema\n outputSchema?: ZodTypeAny;\n description?: string;\n flags?: string[]; // async / mutating / streaming\n }>;\n};\n\nexport interface IEntityViewController {\n modelName: string;\n viewType: string;\n viewId: string;\n describe(): EntityViewCapabilityDescriptor;\n invoke<T = any, R = any>(operator: string, input?: T): Promise<R>;\n}\n\nexport abstract class EntityWidget<P extends EntityWidgetProps = EntityWidgetProps> {\n abstract readonly info: IEntityWidgetMetaInfo;\n\n abstract readonly Component: React.FC<P>;\n}\n\nexport interface IEntityComponentSuiteAdapter {\n suiteName: string;\n\n suiteVersion: string;\n\n getWidget(widgetName: string): EntityWidget | undefined;\n\n getWidgets(): EntityWidget[];\n}\n\nexport interface IEntityNamedRenderer {\n name: string;\n slotName?: string;\n disabled?: boolean;\n renderer: (props: any) => React.ReactNode;\n}\n\nexport interface IEntityComponentRegistry {\n registerView(view: EntityView): void;\n\n registerViewLoader(viewName: string, loader: () => EntityView): void;\n\n getView(viewName: string): EntityView | undefined;\n\n getViews(): EntityView[];\n\n registerAdapter(adapter: IEntityComponentSuiteAdapter): void;\n\n getAdapter(suiteName: string): IEntityComponentSuiteAdapter | undefined;\n\n getAdapters(): IEntityComponentSuiteAdapter[];\n\n registerRenderer(renderer: IEntityNamedRenderer): void;\n\n getRenderer(name: string): IEntityNamedRenderer | undefined;\n\n getRenderersBySlot(slotName: string): IEntityNamedRenderer[];\n\n registerViewController(controller: IEntityViewController): void;\n\n unregisterViewController(viewId: string): void;\n\n getViewController(\n modelName?: string,\n viewType?: string,\n viewId?: string\n ): IEntityViewController | undefined;\n\n getAllViewControllers(): IEntityViewController[];\n}\n","'use client';\n\nimport type { EntityViewProps } from '../../../../components';\n\nimport { useState } from 'react';\nimport { notifications } from '@mantine/notifications';\nimport {\n Text,\n Paper,\n Title,\n Anchor,\n Button,\n Checkbox,\n TextInput,\n PasswordInput,\n} from '@mantine/core';\n\nimport { useEntityEngine, useEntitySession, useMasterDetailViewContainer } from '../../../../uikit';\n\nexport function AuthViewLoginComp(props: EntityViewProps) {\n const { model, baseObjectId, viewData, behavior } = props;\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n const [rememberMe, setRememberMe] = useState(false);\n const [error, setError] = useState('');\n const engine = useEntityEngine();\n const { session, sessionRefresh } = useEntitySession();\n const { performAction } = useMasterDetailViewContainer();\n\n const getCsrfToken = async () => {\n const response = await fetch(engine.settings.getUrl('/auth/csrf'));\n const { csrfToken } = await response.json();\n return csrfToken;\n };\n\n const handleSubmit = async (e: { preventDefault: () => void }) => {\n e.preventDefault();\n\n const csrfToken = await getCsrfToken();\n if (!csrfToken) {\n setError('Could not retrieve CSRF token.');\n return;\n }\n\n // 注意:Auth.js 期望的是 x-www-form-urlencoded 格式的数据\n const body = new URLSearchParams();\n body.append('csrfToken', csrfToken);\n body.append('username', username);\n body.append('password', password);\n body.append('remember', rememberMe ? 'true' : 'false');\n body.append('json', 'true'); // 告诉 Auth.js 返回 JSON 格式的响应\n body.append('redirect', 'false'); // 不要重定向,保持在当前页面\n\n const response = await fetch(engine.settings.getUrl('/auth/callback/credentials'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body,\n });\n\n if (response.ok && response.status === 200) {\n console.log('Login successful', response);\n // 登录成功,浏览器会自动设置 cookie\n // 你可以刷新页面或重定向到受保护的路由\n // window.location.href = '/profile';\n notifications.show({\n title: '登录成功',\n message: '欢迎回来,你已成功登录。',\n color: 'green',\n autoClose: 5000,\n });\n await sessionRefresh?.();\n // performAction({\n // actionType: 'view',\n // payload: {\n // modelName: '__default__',\n // viewType: 'shell',\n // },\n // contextObject: {\n // objectId: '', // newObject.id,\n // },\n // target: '__root__',\n // });\n window.location.reload();\n } else {\n setError('邮箱或密码错误.');\n }\n };\n\n return (\n <div className=\"entity-auth-wrapper\">\n <Paper className=\"entity-auth-form\">\n <Title order={2} className=\"entity-auth-title\">\n 欢迎登录\n </Title>\n <form onSubmit={handleSubmit}>\n {error && <Text c=\"red\">{error}</Text>}\n <TextInput\n label=\"邮箱地址\"\n placeholder=\"hello@gmail.com\"\n size=\"md\"\n radius=\"md\"\n onChange={(e) => setUsername(e.target.value)}\n />\n <PasswordInput\n label=\"登录密码\"\n placeholder=\"Your password\"\n mt=\"md\"\n size=\"md\"\n radius=\"md\"\n onChange={(e) => setPassword(e.target.value)}\n />\n <Checkbox\n label=\"保持登录\"\n mt=\"xl\"\n size=\"md\"\n onChange={(e) => setRememberMe(e.target.checked)}\n />\n <Button\n fullWidth\n mt=\"xl\"\n size=\"md\"\n radius=\"md\"\n type=\"submit\"\n onClick={handleSubmit}\n >\n 登录\n </Button>\n\n <Text ta=\"center\" mt=\"md\">\n 还没有密码?{' '}\n <Anchor href=\"#\" fw={500} onClick={(event) => event.preventDefault()}>\n 注册\n </Anchor>\n </Text>\n </form>\n </Paper>\n </div>\n );\n}\n","import type { EntityViewProps, IEntityViewMetaInfo } from '../../../../components';\n\nimport React from 'react';\n\nimport { EntityView } from '../../../../components';\nimport { AuthViewLoginComp } from './auth-view-comp';\n\nexport class AuthView extends EntityView {\n readonly info: IEntityViewMetaInfo = {\n viewName: 'auth',\n displayName: '认证视图',\n icon: 'auth_icon',\n description: '认证视图, 包含登录、注册等功能',\n };\n\n readonly Component: React.FC<EntityViewProps> = (props) => <AuthViewLoginComp {...props} />;\n}\n\nexport default AuthView;\n"],"mappings":"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","names":["jsx"]}