├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github └── workflows │ └── publish-docker.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .npmrc ├── .prettierignore ├── .standard.jsonc ├── .vscode └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DEVEPLOMENT.md ├── Dockerfile.tpl ├── LICENSE ├── README.md ├── TODO ├── browser-test ├── Dockerfile ├── README.md └── entry.sh ├── collab-server ├── .dockerignore ├── .npmrc ├── Dockerfile ├── README.md ├── index.mjs ├── package.json └── pnpm-lock.yaml ├── deployment ├── README.md ├── generate.js ├── source │ ├── certbot-verify.conf │ ├── default.conf │ ├── docker-compose-prepare-dev.yml │ ├── docker-compose-prepare.yml │ ├── docker-compose.yml │ └── nginx.conf └── variable.sample.jsonc ├── env.d.ts ├── generator-demo ├── README.md └── arch.excalidraw.svg ├── jest.config.js ├── jest.env.js ├── k8s-deployment.zadig ├── lib ├── ai-directive-parser │ ├── exceptions.ts │ ├── index.ts │ ├── parser.test.ts │ └── parser.ts ├── api │ ├── index.ts │ └── method.ts ├── chat-bot │ ├── BotContext.tsx │ ├── BotEvent.ts │ ├── BotModel.ts │ ├── BotPageEvent.ts │ ├── BotPageModel.tsx │ ├── BotPagePersister.ts │ ├── BotPersister.ts │ ├── BotPromptLibraryContext.tsx │ ├── BotPromptLibraryModel.ts │ ├── BotSession.ts │ ├── BotSessionPersister.ts │ ├── BotSessionStore.tsx │ ├── BotSessionStoreContext.tsx │ ├── BotSessionStoreEvent.ts │ ├── BotWindowEvent.ts │ ├── BotWindowKeyBinding.tsx │ ├── BotWindowModel.tsx │ ├── BotWindowPersister.ts │ ├── ChatPage │ │ ├── ChatPage.module.scss │ │ ├── ChatPage.tsx │ │ ├── Content.module.scss │ │ ├── Content.tsx │ │ ├── ExploreIcon.tsx │ │ ├── Sidebar.module.scss │ │ ├── Sidebar.tsx │ │ ├── SidebarIcon.tsx │ │ ├── index.tsx │ │ └── robot.png │ ├── ChatWindow │ │ ├── ChatWindow.module.scss │ │ ├── ChatWindow.tsx │ │ ├── CopyIcon.tsx │ │ ├── History.module.scss │ │ ├── History.tsx │ │ ├── NewWindowIcon.tsx │ │ ├── Prompt.module.scss │ │ ├── Prompt.tsx │ │ ├── StopIcon.tsx │ │ └── index.tsx │ ├── PromptLibrary │ │ ├── Card.module.scss │ │ ├── Card.tsx │ │ ├── List.module.scss │ │ ├── List.tsx │ │ ├── Modal.module.scss │ │ ├── Modal.tsx │ │ ├── README.md │ │ ├── index.tsx │ │ └── types.ts │ ├── README.md │ ├── chat-context.test.ts │ ├── chat-context.ts │ ├── constants.ts │ ├── extensions │ │ ├── bug.ts │ │ ├── clear.ts │ │ ├── index.ts │ │ └── list.ts │ ├── helpers.ts │ ├── index.tsx │ ├── protocol.ts │ ├── registry.ts │ ├── tokenizer.ts │ ├── types.ts │ ├── util.ts │ └── utils.test.ts ├── components │ ├── ColorInput │ │ ├── ColorHistory.ts │ │ ├── ColorPalette.module.scss │ │ ├── ColorPalette.tsx │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Completion │ │ ├── Completion.tsx │ │ ├── CompletionContext.tsx │ │ ├── CompletionImplement.test.ts │ │ ├── CompletionImplement.ts │ │ ├── index.ts │ │ ├── type.ts │ │ ├── utils.test.ts │ │ └── utils.ts │ ├── ContentEditable │ │ └── index.tsx │ ├── DescriptionInput │ │ └── index.tsx │ ├── DynamicSlot │ │ └── index.tsx │ ├── FullScreenContainer │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Import │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Markdown │ │ ├── CodePreviewPlugin.tsx │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Mermaid │ │ ├── Container.module.scss │ │ ├── Container.tsx │ │ ├── MermaidComponent.tsx │ │ ├── MindMap.tsx │ │ ├── index.ts │ │ ├── types.ts │ │ ├── utils.test.tsx │ │ └── utils.ts │ ├── NameInput │ │ ├── index.module.scss │ │ ├── index.tsx │ │ ├── useAutoCompleteUbiquitousLanguage.ts │ │ ├── utils.test.ts │ │ └── utils.ts │ ├── OfflineTip │ │ └── index.tsx │ ├── PreviewPageLayout │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Prompt │ │ ├── index.module.scss │ │ └── index.tsx │ ├── SortableList │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Title │ │ └── index.tsx │ ├── TitleInput │ │ └── index.tsx │ ├── UbiquitousLanguageCompletion │ │ ├── Context.tsx │ │ ├── README.md │ │ └── index.ts │ ├── VersionBadge │ │ ├── index.module.scss │ │ └── index.tsx │ ├── VersionControl │ │ ├── README.md │ │ ├── VersionCreate.tsx │ │ ├── VersionList.tsx │ │ ├── VersionPublish.tsx │ │ ├── index.ts │ │ └── types.ts │ └── validator.ts ├── contants │ ├── index.ts │ └── keybinding.ts ├── core │ ├── constants.ts │ ├── index.ts │ └── types.ts ├── designer │ ├── BaseDesignerContext.tsx │ ├── BaseDesignerModel.ts │ ├── DesignerAwareness.ts │ ├── DesignerAwarenessDelegate.ts │ ├── DesignerKeyboardBinding.ts │ ├── HistoryManager.ts │ ├── IDesigner.ts │ ├── IDesignerTab.ts │ ├── components │ │ ├── DesignerLayout │ │ │ ├── Header │ │ │ │ ├── CollabStatus.module.scss │ │ │ │ ├── CollabStatus.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Layout │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── Loading │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── README.md │ │ │ ├── TabLabel │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ ├── DiffView.module.scss │ │ ├── DiffView.tsx │ │ ├── HistoryView.module.scss │ │ ├── HistoryView.tsx │ │ ├── HistoryViewModal.tsx │ │ ├── VersionSelect.tsx │ │ └── index.tsx │ ├── createYjsProvider.ts │ └── index.ts ├── dom │ └── index.ts ├── editor │ ├── Canvas │ │ ├── Awareness.module.scss │ │ ├── Awareness.tsx │ │ ├── Canvas.module.scss │ │ ├── Canvas.tsx │ │ ├── CanvasEvent.ts │ │ ├── CanvasModel.ts │ │ ├── CanvasModelContext.tsx │ │ ├── Cells.tsx │ │ ├── ClipboardUtils.ts │ │ ├── ContextMenu.module.scss │ │ ├── ContextMenu.tsx │ │ ├── ContextMenuController.ts │ │ ├── KeyboardBinding.ts │ │ ├── README.md │ │ ├── exportAsImage.ts │ │ ├── index.ts │ │ └── layout.ts │ ├── Model │ │ ├── BaseEditorCommandHandler.ts │ │ ├── BaseEditorDatasource.ts │ │ ├── BaseEditorEvent.ts │ │ ├── BaseEditorFormStore.ts │ │ ├── BaseEditorIndex.ts │ │ ├── BaseEditorModel.ts │ │ ├── BaseEditorPropertyLocationObserver.test.ts │ │ ├── BaseEditorPropertyLocationObserver.ts │ │ ├── BaseEditorScope.ts │ │ ├── BaseEditorStore.ts │ │ ├── BaseEditorValidateManager.ts │ │ ├── BaseEditorViewStore.ts │ │ ├── BaseNode.ts │ │ ├── EditorModelContext.ts │ │ ├── FormModel │ │ │ ├── FormModel.ts │ │ │ ├── StatusTree.test.ts │ │ │ ├── StatusTree.ts │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── utils.test.ts │ │ │ └── utils.ts │ │ ├── README.md │ │ ├── Yjs │ │ │ ├── Builder.test.ts │ │ │ ├── Builder.ts │ │ │ ├── NodeYMap.test.ts │ │ │ ├── NodeYMap.ts │ │ │ ├── __snapshots__ │ │ │ │ └── Builder.test.ts.snap │ │ │ ├── index.ts │ │ │ ├── sync.test.ts │ │ │ └── sync.ts │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── mapper.ts │ │ └── types.ts │ ├── Shape │ │ ├── ShapeRegistry.ts │ │ ├── ShapeRenderer.tsx │ │ ├── builtin │ │ │ ├── README.md │ │ │ ├── activity.png │ │ │ ├── activity.tsx │ │ │ ├── comment.module.scss │ │ │ ├── comment.png │ │ │ ├── comment.tsx │ │ │ ├── constants.ts │ │ │ ├── edge.tsx │ │ │ └── index.ts │ │ ├── constants.ts │ │ ├── defineShape.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useHoverShowPorts.ts │ │ │ └── useShapeModel.ts │ │ ├── index.ts │ │ ├── react-component-decorators │ │ │ ├── AutoResize.tsx │ │ │ ├── FormStatus.module.scss │ │ │ ├── FormStatus.tsx │ │ │ ├── Observer.tsx │ │ │ ├── README.md │ │ │ └── index.ts │ │ ├── store.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── components │ │ ├── Attributes │ │ │ ├── README.md │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Configuration │ │ │ └── index.tsx │ │ ├── Form │ │ │ ├── Form.tsx │ │ │ ├── FormCollapse.module.scss │ │ │ ├── FormCollapse.tsx │ │ │ ├── FormConsumer.tsx │ │ │ ├── FormContainer.module.scss │ │ │ ├── FormContainer.tsx │ │ │ ├── FormContext.tsx │ │ │ ├── FormIssues.module.scss │ │ │ ├── FormIssues.tsx │ │ │ ├── FormItem.module.scss │ │ │ ├── FormItem.tsx │ │ │ ├── FormPortal │ │ │ │ ├── context.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── FormRevalidateSpin.module.scss │ │ │ ├── FormRevalidateSpin.tsx │ │ │ ├── FormTooltip.module.scss │ │ │ ├── FormTooltip.tsx │ │ │ └── index.ts │ │ ├── InspectPanel │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Layout │ │ │ ├── PanelLayout.tsx │ │ │ ├── SidebarFolder.module.scss │ │ │ ├── SidebarFolder.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── NodeVisibleControl │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Panel │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Problems │ │ │ ├── README.md │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── SelectNodePlease │ │ │ └── index.tsx │ │ ├── ShapeLibrary │ │ │ ├── ShapeItem │ │ │ │ ├── default-logo.svg │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Toolbar │ │ │ ├── GrabIcon.tsx │ │ │ ├── SelectIcon.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ └── index.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useCanvasModelCommandDescription.ts │ │ ├── usePropertyLocationNavigate.ts │ │ └── usePropertyLocationSatisfy.ts │ └── index.ts ├── framework │ ├── base │ │ ├── BaseModel.ts │ │ └── index.ts │ ├── components │ │ ├── DIContainerContext.tsx │ │ ├── DIContainerProvider.tsx │ │ ├── README.md │ │ └── index.ts │ ├── di │ │ ├── index.ts │ │ ├── methods.test.ts │ │ └── methods.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useDIContainer.test.ts │ │ ├── useDIContainer.ts │ │ ├── useEventBus.test.ts │ │ ├── useEventBus.ts │ │ ├── useEventBusListener.test.ts │ │ ├── useEventBusListener.ts │ │ ├── useInject.test.ts │ │ ├── useInject.ts │ │ ├── useInjectAll.test.ts │ │ ├── useInjectAll.ts │ │ ├── useInjectComponent.test.ts │ │ ├── useInjectComponent.ts │ │ └── useMultiInject.ts │ ├── index.test.ts │ ├── index.ts │ ├── initialize.ts │ ├── mobx.test.tsx │ └── polyfill.ts ├── g6-binding │ ├── CellBinding │ │ ├── CellUpdater.ts │ │ ├── context.ts │ │ ├── index.tsx │ │ ├── types.ts │ │ └── useCell.ts │ ├── EdgeBinding │ │ ├── index.tsx │ │ ├── types.ts │ │ └── useEdge.tsx │ ├── GraphBinding │ │ ├── GraphBindingContext.tsx │ │ └── index.tsx │ ├── NodeBinding │ │ ├── index.tsx │ │ ├── types.ts │ │ └── useNode.ts │ ├── NodeShapeBinding │ │ ├── ReactComponentBinding.tsx │ │ ├── RectBinding.tsx │ │ ├── createShape.tsx │ │ └── index.tsx │ ├── README.md │ ├── ReactTools │ │ ├── BBox.module.scss │ │ ├── BBox.tsx │ │ └── index.ts │ ├── hooks │ │ ├── index.ts │ │ └── useEventStore.ts │ ├── index.ts │ └── react-shape │ │ ├── README.md │ │ ├── index.ts │ │ ├── node.tsx │ │ ├── portal.tsx │ │ ├── registry.tsx │ │ ├── view.tsx │ │ └── wrap.tsx ├── hooks │ ├── index.ts │ ├── useEventBusListener.test.ts │ ├── useEventBusListener.ts │ ├── useIsMacos.ts │ ├── useLazyFalsy.ts │ ├── useOffline.ts │ ├── usePreventUnload.ts │ ├── useReadableKeyBinding.ts │ ├── useSyncEffect.test.ts │ ├── useSyncEffect.ts │ └── useTimeout.ts ├── middleware │ ├── index.test.ts │ └── index.ts ├── monaco-editor │ ├── index.tsx │ └── loader.ts ├── openai-event-source │ ├── Loading.module.scss │ ├── Loading.tsx │ ├── LoadingIcon.tsx │ ├── OpenAIEventSourceModel.ts │ ├── PromptModal.module.scss │ ├── PromptModal.tsx │ ├── decode.test.ts │ ├── decode.ts │ ├── index.ts │ ├── stream.ts │ └── useOpenAI.ts ├── polyfill │ └── index.ts ├── store │ ├── README.md │ ├── auto-bind-this.test.ts │ ├── auto-bind-this.ts │ ├── command.ts │ ├── derive.test.ts │ ├── derive.ts │ ├── effect.ts │ ├── index.ts │ ├── mutation.ts │ ├── pull.ts │ └── push.ts ├── typescript │ ├── README.md │ ├── comment.test.ts │ ├── comment.ts │ ├── enum.test.ts │ ├── enum.ts │ ├── index.ts │ ├── interface.test.ts │ ├── interface.ts │ ├── types.ts │ ├── utils.test.ts │ └── utils.ts ├── utils │ ├── Clipboard.ts │ ├── EventBus.test.ts │ ├── EventBus.ts │ ├── IDestroyable.ts │ ├── IDisposable.ts │ ├── ISerializable.ts │ ├── IdleTaskExecutor.ts │ ├── KeyboardBinding.test.ts │ ├── KeyboardBinding.ts │ ├── TimeoutController.test.ts │ ├── TimeoutController.ts │ ├── abort.ts │ ├── array.test.ts │ ├── array.ts │ ├── assert.test.ts │ ├── assert.ts │ ├── color.test.ts │ ├── color.ts │ ├── filter.ts │ ├── hash.test.ts │ ├── hash.ts │ ├── index.ts │ ├── name-case.test.ts │ ├── name-case.ts │ ├── object.test.ts │ ├── object.ts │ ├── price.ts │ ├── promise.ts │ ├── url.test.ts │ └── url.ts ├── wysiwyg-editor │ ├── CodeBlockComponent.module.scss │ ├── CodeBlockComponent.tsx │ ├── CustomBlock │ │ ├── CodeSandbox.tsx │ │ ├── Demo.tsx │ │ ├── ExpandIcon.tsx │ │ ├── OpenIcon.tsx │ │ ├── ProcessOn.tsx │ │ ├── ProcessOnIcon.tsx │ │ ├── ThirdPartyBlock.module.scss │ │ ├── ThirdPartyBlock.tsx │ │ └── index.ts │ ├── CustomKeyboardBinding.ts │ ├── DBlock │ │ ├── DBlockNodeView.tsx │ │ ├── index.module.scss │ │ └── index.ts │ ├── Document.tsx │ ├── FileHandler.ts │ ├── Marks │ │ ├── index.module.scss │ │ └── index.tsx │ ├── README.md │ ├── ReactBlock │ │ ├── Extension.ts │ │ ├── README.md │ │ ├── ReactBlockComponent.module.scss │ │ ├── ReactBlockComponent.tsx │ │ ├── index.ts │ │ └── registry.ts │ ├── StaticEditor.tsx │ ├── Suggestion │ │ ├── CommandList.module.scss │ │ ├── CommandList.tsx │ │ ├── Commands.ts │ │ ├── README.md │ │ ├── icons │ │ │ ├── Bold.tsx │ │ │ ├── Code.tsx │ │ │ ├── Default.tsx │ │ │ ├── H1.tsx │ │ │ ├── H2.tsx │ │ │ ├── H3.tsx │ │ │ ├── H4.tsx │ │ │ ├── List.tsx │ │ │ ├── ListOrder.tsx │ │ │ ├── Paragraph.tsx │ │ │ ├── Quote.tsx │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── items.ts │ │ ├── renderItem.tsx │ │ ├── suggestion │ │ │ ├── findSuggestionMatch.ts │ │ │ ├── index.ts │ │ │ └── suggestion.ts │ │ └── types.ts │ ├── Toolbar │ │ ├── CodeIcon.tsx │ │ ├── ImageEditor.module.scss │ │ ├── ImageEditor.tsx │ │ ├── JustifyIcon.tsx │ │ ├── LinkEditor.module.scss │ │ ├── LinkEditor.tsx │ │ ├── index.module.scss │ │ └── index.tsx │ ├── common.module.scss │ ├── constants.ts │ ├── index.module.scss │ ├── index.tsx │ └── utils.ts ├── yjs-reverse │ ├── README.md │ ├── index.test.ts │ └── index.ts ├── yjs-store-api-for-browser │ ├── index.ts │ ├── raw.test.ts │ └── raw.ts ├── yjs-store-api │ ├── index.ts │ ├── raw.test.ts │ ├── raw.ts │ ├── utils.test.ts │ └── utils.ts └── yjs-xml-fragment │ ├── __snapshots__ │ └── index.test.ts.snap │ ├── index.data.json │ ├── index.test.ts │ └── index.ts ├── middleware.ts ├── modules ├── Layout │ ├── Content.module.scss │ ├── Content.tsx │ ├── Context.tsx │ ├── Header.module.scss │ ├── Header.tsx │ ├── Layout.module.scss │ ├── Layout.tsx │ ├── LogoIcon.tsx │ ├── Sidebar.module.scss │ ├── Sidebar.tsx │ ├── User.module.scss │ ├── User.tsx │ ├── index.ts │ ├── types.ts │ └── utils.ts ├── ai │ ├── api │ │ ├── chat-supported.ts │ │ ├── dall-e.ts │ │ ├── data-object-builder.ts │ │ ├── data-object.ts │ │ ├── ddd-master.ts │ │ ├── echo.ts │ │ ├── extra-words.ts │ │ ├── fallback.ts │ │ ├── flow-builder.ts │ │ ├── free-usage.ts │ │ ├── index.ts │ │ ├── models.ts │ │ ├── proxy.ts │ │ ├── sql-master.ts │ │ ├── subject.ts │ │ ├── summary.ts │ │ ├── vision.ts │ │ ├── wakeadmin-form.ts │ │ ├── wakeadmin-table.ts │ │ └── words-to-ubiquitous-language.ts │ ├── chat.ts │ ├── constants.ts │ ├── encoding.ts │ ├── index.ts │ ├── openai.ts │ ├── plans.ts │ ├── platform │ │ ├── AzureChatCompletionSupport.ts │ │ ├── OpenAIChatCompletionSupport.ts │ │ ├── OpenAISupportImplement.ts │ │ ├── index.ts │ │ └── types.ts │ ├── rate-limit │ │ ├── AmountWindowLimit.test.ts │ │ ├── AmountWindowLimit.ts │ │ ├── CountLimit.test.ts │ │ ├── CountLimit.ts │ │ ├── CountWindowLimit.test.ts │ │ ├── CountWindowLimit.ts │ │ ├── FreeAccountRateLimit.test.ts │ │ ├── FreeAccountRateLimit.ts │ │ ├── GPT35Limit.ts │ │ ├── GPT35RateLimit.ts │ │ ├── GPT4Limit.ts │ │ ├── GPT4RateLimit.ts │ │ ├── IRateLimit.ts │ │ ├── README.md │ │ └── index.ts │ ├── request-control │ │ ├── RequestControlChain.ts │ │ ├── index.ts │ │ ├── planCheck.ts │ │ └── rate-limit-check.ts │ ├── shared.ts │ ├── types.ts │ └── usage │ │ ├── README.md │ │ └── index.ts ├── backend-client │ ├── README.md │ ├── constants.ts │ ├── download.ts │ ├── fetch.ts │ ├── helper.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useCacheableRequest.ts │ │ ├── useCleanRequestCache.ts │ │ ├── useRequest.ts │ │ ├── useRequestByGet.ts │ │ └── useRequestByPost.ts │ ├── index.ts │ └── request.ts ├── backend-node │ ├── README.md │ ├── constants.ts │ ├── index.ts │ ├── merge-cookie.test.ts │ ├── merge-cookie.ts │ ├── middleware.ts │ ├── parse-set-cookie.test.ts │ ├── parse-set-cookie.ts │ ├── predicate.ts │ ├── request.ts │ └── serialize-cookie.ts ├── chat-bot │ ├── BotButton.tsx │ ├── BotIcon.tsx │ ├── RocketIcon.tsx │ ├── ShowBotWhenLogged.tsx │ ├── StandalonePage.module.scss │ ├── StandalonePage.tsx │ ├── UserCard.module.scss │ ├── UserCard.tsx │ ├── extensions │ │ ├── dall-e.ts │ │ ├── ddd-master.ts │ │ ├── echo.ts │ │ ├── global.ts │ │ └── index.ts │ └── hooks │ │ ├── index.ts │ │ └── useChatSupported.ts ├── document-layout │ ├── Header.module.scss │ ├── Header.tsx │ ├── HeadingMenu.module.scss │ ├── HeadingMenu.tsx │ ├── Layout.module.scss │ ├── Layout.tsx │ ├── Navigation.module.scss │ ├── Navigation.tsx │ └── index.tsx ├── domain │ ├── Designer │ │ ├── Context.tsx │ │ ├── Header │ │ │ └── index.tsx │ │ ├── Loading │ │ │ └── index.tsx │ │ ├── index.tsx │ │ └── model │ │ │ ├── DomainDesignerEvent.ts │ │ │ ├── DomainDesignerModel.ts │ │ │ ├── ObjectStore.ts │ │ │ ├── constants.ts │ │ │ └── index.ts │ ├── README.md │ ├── api │ │ ├── dsl │ │ │ ├── IObjectStore.ts │ │ │ ├── __snapshots__ │ │ │ │ ├── data-model.test.ts.snap │ │ │ │ ├── doc.test.ts.snap │ │ │ │ ├── domain-model.test.ts.snap │ │ │ │ ├── model.test.ts.snap │ │ │ │ └── query-model.test.ts.snap │ │ │ ├── data-model.test.ts │ │ │ ├── data-model.ts │ │ │ ├── doc.test.ts │ │ │ ├── doc.ts │ │ │ ├── domain-model.data.json │ │ │ ├── domain-model.test.ts │ │ │ ├── domain-model.ts │ │ │ ├── interface.ts │ │ │ ├── mapper-model.test.ts │ │ │ ├── mapper-model.ts │ │ │ ├── model.test.ts │ │ │ ├── model.ts │ │ │ ├── product-template.ts │ │ │ ├── query-model.test.ts │ │ │ ├── query-model.ts │ │ │ └── shared.ts │ │ ├── index.ts │ │ └── utils.ts │ ├── constants.ts │ ├── data-design │ │ ├── StandaloneDataObjectEditor.tsx │ │ ├── ai-dsl │ │ │ ├── __snapshots__ │ │ │ │ └── transform.test.ts.snap │ │ │ ├── index.ts │ │ │ ├── transform.test.ts │ │ │ └── transform.ts │ │ ├── ai-import │ │ │ ├── __snapshots__ │ │ │ │ └── transform.test.ts.snap │ │ │ ├── dsl.ts │ │ │ ├── index.ts │ │ │ ├── transform.test.ts │ │ │ └── transform.ts │ │ ├── ai-transformer │ │ │ ├── README.md │ │ │ ├── __snapshots__ │ │ │ │ └── parser.test.ts.snap │ │ │ ├── executor.ts │ │ │ ├── index.ts │ │ │ ├── parser.test.ts │ │ │ ├── parser.ts │ │ │ └── protocol.ts │ │ ├── bot-extension │ │ │ ├── create.ts │ │ │ ├── dataObject │ │ │ │ ├── Table.tsx │ │ │ │ ├── TableStore.tsx │ │ │ │ ├── dataObject.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── sqlMaster.tsx │ │ ├── components │ │ │ ├── AIModal.module.scss │ │ │ ├── AIModal.tsx │ │ │ ├── DataObjectEditor.tsx │ │ │ ├── DataObjectReferenceEdges.tsx │ │ │ ├── ShapeTitle.tsx │ │ │ ├── ShapeTree.module.scss │ │ │ ├── ShapeTree.tsx │ │ │ ├── StandaloneDataObjectEditor.module.scss │ │ │ ├── StandaloneDataObjectEditor.tsx │ │ │ └── index.ts │ │ ├── dsl │ │ │ ├── constants.ts │ │ │ ├── dsl.ts │ │ │ ├── factory.ts │ │ │ └── index.ts │ │ ├── factory.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── DataObject.ts │ │ │ ├── DataObjectEditorModel.ts │ │ │ ├── DataObjectEvent.ts │ │ │ ├── DataObjectStore.ts │ │ │ ├── DataObjectValidateManager.ts │ │ │ └── index.ts │ │ └── shape │ │ │ ├── DataObject │ │ │ ├── DataObjectEditor.tsx │ │ │ ├── DataObjectShape.module.scss │ │ │ ├── DataObjectShape.tsx │ │ │ ├── IndexesEditor.tsx │ │ │ ├── KeyIcon.tsx │ │ │ ├── PrimaryKeyRenderer.module.scss │ │ │ ├── PrimaryKeyRenderer.tsx │ │ │ ├── PropertiesEditor.module.scss │ │ │ ├── PropertiesEditor.tsx │ │ │ ├── PropertyDefaultValue.tsx │ │ │ ├── ReferenceEditor.tsx │ │ │ ├── RequireRenderer.module.scss │ │ │ ├── RequireRenderer.tsx │ │ │ ├── TypeRenderer.module.scss │ │ │ ├── TypeRenderer.tsx │ │ │ ├── data-object.png │ │ │ ├── index.tsx │ │ │ ├── reactify.module.scss │ │ │ ├── reactify.tsx │ │ │ └── validator.ts │ │ │ └── index.ts │ ├── domain-design │ │ ├── README.md │ │ ├── StandaloneDomainEditor.tsx │ │ ├── bot-extension │ │ │ ├── index.ts │ │ │ ├── wakeadmin-form.ts │ │ │ └── wakeadmin-table.ts │ │ ├── components │ │ │ ├── DomainEditor.tsx │ │ │ ├── DomainObjectReferenceEdges.tsx │ │ │ ├── RelationShipSelect │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── ShapeTitle │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── ShapeTree │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── StandaloneDomainEditor.module.scss │ │ │ ├── StandaloneDomainEditor.tsx │ │ │ └── index.ts │ │ ├── dsl │ │ │ ├── components │ │ │ │ ├── AccessSelect.tsx │ │ │ │ ├── AggregationSelect │ │ │ │ │ └── index.tsx │ │ │ │ ├── ClassShape │ │ │ │ │ ├── ClassShape.module.scss │ │ │ │ │ ├── ClassShape.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── CommandOrQuerySelect │ │ │ │ │ └── index.tsx │ │ │ │ ├── DescriptionInput │ │ │ │ │ └── index.tsx │ │ │ │ ├── MemberList │ │ │ │ │ ├── MemberEditor.module.scss │ │ │ │ │ ├── MemberEditor.tsx │ │ │ │ │ ├── MemberList.module.scss │ │ │ │ │ ├── MemberList.tsx │ │ │ │ │ ├── README.md │ │ │ │ │ └── index.ts │ │ │ │ ├── MethodsEditor │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── NameInput │ │ │ │ │ └── index.tsx │ │ │ │ ├── ObjectNameInput │ │ │ │ │ └── index.tsx │ │ │ │ ├── ParameterEditor │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── PropertiesEditor │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── ReferenceTypeDisplay │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── SourceInput │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── TitleInput │ │ │ │ │ └── index.tsx │ │ │ │ ├── TypeInput │ │ │ │ │ ├── TypeInput.tsx │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ └── index.ts │ │ │ ├── constants.ts │ │ │ ├── dependency.test.ts │ │ │ ├── dependency.ts │ │ │ ├── dsl.ts │ │ │ ├── factory.ts │ │ │ ├── helper.test.ts │ │ │ ├── helper.ts │ │ │ ├── index.ts │ │ │ ├── reactify.tsx │ │ │ ├── stringify.test.ts │ │ │ ├── stringify.ts │ │ │ └── validators.ts │ │ ├── factory.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ └── useAutoCompleteUbiquitousLanguageFromFormModel.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── DomainEditorModel.ts │ │ │ ├── DomainEditorViewModel.ts │ │ │ ├── DomainObject.ts │ │ │ ├── DomainObjectAggregation.ts │ │ │ ├── DomainObjectClass.ts │ │ │ ├── DomainObjectCommand.ts │ │ │ ├── DomainObjectDTO.ts │ │ │ ├── DomainObjectEntity.ts │ │ │ ├── DomainObjectEnum.ts │ │ │ ├── DomainObjectEvent.ts │ │ │ ├── DomainObjectFactory.ts │ │ │ ├── DomainObjectQuery.ts │ │ │ ├── DomainObjectRule.ts │ │ │ ├── DomainObjectStore.ts │ │ │ ├── DomainObjectUnderAggregation.ts │ │ │ ├── DomainObjectValueObject.ts │ │ │ ├── DomainValidateManager.ts │ │ │ ├── IEdgeDeclaration.ts │ │ │ ├── index.ts │ │ │ └── toTypescriptInterface.ts │ │ └── shape │ │ │ ├── Aggregation │ │ │ ├── AggregationEditor │ │ │ │ └── index.tsx │ │ │ ├── AggregationShape │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── aggregation.png │ │ │ └── index.tsx │ │ │ ├── Command │ │ │ ├── Command.tsx │ │ │ ├── CommandEditor │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── CommandShape │ │ │ │ ├── CommandShape.module.scss │ │ │ │ ├── CommandShape.tsx │ │ │ │ └── index.ts │ │ │ ├── command.png │ │ │ └── index.ts │ │ │ ├── DTO │ │ │ ├── DTO.tsx │ │ │ ├── DTOEditor │ │ │ │ └── index.tsx │ │ │ ├── dto.png │ │ │ └── index.ts │ │ │ ├── Entity │ │ │ ├── EntityEditor │ │ │ │ └── index.tsx │ │ │ ├── entity.png │ │ │ └── index.tsx │ │ │ ├── Enum │ │ │ ├── Enum.tsx │ │ │ ├── EnumEditor │ │ │ │ ├── EnumMembersEditor │ │ │ │ │ ├── index.module.scss │ │ │ │ │ └── index.tsx │ │ │ │ └── index.tsx │ │ │ ├── EnumShape │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── enum.png │ │ │ └── index.ts │ │ │ ├── Query │ │ │ ├── Query.tsx │ │ │ ├── QueryEditor │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.ts │ │ │ └── query.png │ │ │ ├── README.md │ │ │ ├── Rule │ │ │ ├── Rule.tsx │ │ │ ├── RuleEditor │ │ │ │ └── index.tsx │ │ │ ├── RuleShape │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── index.ts │ │ │ └── rule.png │ │ │ ├── ValueObject │ │ │ ├── ValueObject.tsx │ │ │ ├── ValueObjectEditor │ │ │ │ └── index.tsx │ │ │ ├── index.ts │ │ │ └── value-object.png │ │ │ └── index.ts │ ├── generator │ │ ├── BaseGenerator.ts │ │ ├── BaseGeneratorState.ts │ │ ├── FromAggregationRootDSLGenerator.test.ts │ │ ├── FromAggregationRootDSLGenerator.ts │ │ ├── FromEntityDSLGenerator.test.ts │ │ ├── FromEntityDSLGenerator.ts │ │ ├── FromEnumDSLGenerator.test.ts │ │ ├── FromEnumDSLGenerator.ts │ │ ├── FromValueObjectDSLGenerator.test.ts │ │ ├── FromValueObjectDSLGenerator.ts │ │ ├── README.md │ │ ├── __snapshots__ │ │ │ ├── FromAggregationRootDSLGenerator.test.ts.snap │ │ │ ├── FromEntityDSLGenerator.test.ts.snap │ │ │ └── FromValueObjectDSLGenerator.test.ts.snap │ │ ├── index.ts │ │ ├── public-types.ts │ │ ├── transform.test.ts │ │ ├── transform.ts │ │ └── types.ts │ ├── mapper-design │ │ ├── README.md │ │ ├── components │ │ │ ├── MapperEditor.tsx │ │ │ ├── ShapeTitle.tsx │ │ │ ├── ShapeTree.tsx │ │ │ └── index.ts │ │ ├── dsl │ │ │ ├── compatible.test.ts │ │ │ ├── compatible.ts │ │ │ ├── constants.ts │ │ │ ├── dsl.ts │ │ │ ├── factory.ts │ │ │ └── index.ts │ │ ├── factory.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── IFieldMapper.ts │ │ │ ├── IObjectStore.ts │ │ │ ├── ISourceObject.ts │ │ │ ├── ITargetObject.ts │ │ │ ├── Mapper.ts │ │ │ ├── MapperEditorModel.ts │ │ │ ├── MapperStore.ts │ │ │ ├── MapperValidateManager.ts │ │ │ ├── auto-mapper.test.ts │ │ │ ├── auto-mapper.ts │ │ │ └── index.ts │ │ └── shape │ │ │ ├── Mapper │ │ │ ├── Editor.tsx │ │ │ ├── FieldMapperDisplay.module.scss │ │ │ ├── FieldMapperDisplay.tsx │ │ │ ├── MappersList.tsx │ │ │ ├── ObjectMapperDisplay.module.scss │ │ │ ├── ObjectMapperDisplay.tsx │ │ │ ├── ObjectSelect.tsx │ │ │ ├── Shape.module.scss │ │ │ ├── Shape.tsx │ │ │ ├── SourceFieldSelect.tsx │ │ │ ├── TargetFieldSelect.tsx │ │ │ ├── Title.tsx │ │ │ ├── index.tsx │ │ │ ├── mapper.png │ │ │ ├── reactify.tsx │ │ │ ├── useMapper.ts │ │ │ └── validator.ts │ │ │ └── index.ts │ ├── product-design │ │ └── index.tsx │ ├── query-design │ │ ├── README.md │ │ ├── factory.ts │ │ └── index.ts │ ├── transform │ │ ├── ClassLike.ts │ │ ├── Command.ts │ │ ├── DTO.ts │ │ ├── Entity.ts │ │ ├── PropertiesLike.ts │ │ ├── Query.ts │ │ ├── README.md │ │ ├── Transform.ts │ │ ├── ValueObject.ts │ │ ├── index.test.ts │ │ └── index.ts │ ├── ubiquitous-language-design │ │ ├── AIImport.module.scss │ │ ├── AIImport.tsx │ │ ├── List.module.scss │ │ ├── List.tsx │ │ ├── README.md │ │ ├── UbiquitousLanguageEvents.ts │ │ ├── UbiquitousLanguageFuseStore.ts │ │ ├── UbiquitousLanguageModel.ts │ │ ├── Yjs │ │ │ ├── Builder.test.ts │ │ │ ├── Builder.ts │ │ │ ├── ItemWrapper.ts │ │ │ └── index.ts │ │ ├── index.tsx │ │ └── types.ts │ └── vision-design │ │ ├── VisionDesign.module.scss │ │ ├── VisionDesign.tsx │ │ ├── example-ou.png │ │ ├── index.tsx │ │ └── useVisionBot.tsx ├── dsl-delta │ ├── README.md │ ├── __snapshots__ │ │ └── dsl-delta.test.ts.snap │ ├── diff.test.ts │ ├── diff.ts │ ├── dsl-delta.test.ts │ ├── dsl-delta.ts │ ├── meta.ts │ └── protocol.ts ├── home │ ├── index.module.scss │ ├── index.tsx │ └── pic.png ├── not-found │ ├── index.module.scss │ └── index.tsx ├── organization │ ├── Organization │ │ ├── BaseInfo.tsx │ │ ├── CreateTeam.tsx │ │ ├── RoleSelect.tsx │ │ ├── TeamMember.module.scss │ │ ├── TeamMember.tsx │ │ ├── UpdateTeam.module.scss │ │ ├── UpdateTeam.tsx │ │ ├── index.module.scss │ │ └── index.tsx │ ├── OrganizationLayout │ │ └── index.tsx │ └── types.ts ├── redis │ └── index.ts ├── scenario │ ├── Designer │ │ ├── Context.tsx │ │ ├── index.tsx │ │ └── model │ │ │ ├── DomainServiceStore.ts │ │ │ ├── KeyboardBinding.ts │ │ │ ├── ScenarioDesignerModel.ts │ │ │ ├── ScenarioServiceStore.ts │ │ │ ├── constants.ts │ │ │ └── index.ts │ ├── README.md │ ├── api │ │ ├── dsl │ │ │ ├── __snapshots__ │ │ │ │ ├── doc.test.ts.snap │ │ │ │ └── scenario-model.test.ts.snap │ │ │ ├── doc.test.ts │ │ │ ├── doc.ts │ │ │ ├── index.ts │ │ │ ├── interface.ts │ │ │ ├── model.ts │ │ │ ├── scenario-model.test.ts │ │ │ └── scenario-model.ts │ │ ├── index.ts │ │ └── utils.ts │ ├── constants.ts │ ├── scenario-design │ │ ├── README.md │ │ ├── StandaloneEditor.tsx │ │ ├── ai-transformer │ │ │ ├── executor.test.ts │ │ │ ├── executor.ts │ │ │ ├── index.ts │ │ │ ├── layout.ts │ │ │ ├── parser.test.ts │ │ │ ├── parser.ts │ │ │ └── protocol.ts │ │ ├── bot-extensions │ │ │ ├── index.ts │ │ │ └── scenario │ │ │ │ └── index.ts │ │ ├── components │ │ │ ├── ScenarioEditor.tsx │ │ │ ├── ScenarioStandalone.module.scss │ │ │ ├── ScenarioStandalone.tsx │ │ │ └── index.ts │ │ ├── dsl │ │ │ ├── constants.ts │ │ │ ├── dsl.ts │ │ │ ├── factory.ts │ │ │ └── index.ts │ │ ├── factory.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── IDomainServiceStore.ts │ │ │ ├── IServiceStore.ts │ │ │ ├── ScenarioEditorModel.ts │ │ │ ├── ScenarioValidateManager.ts │ │ │ └── index.ts │ │ └── shape │ │ │ ├── Activity │ │ │ ├── ActivityEditor.tsx │ │ │ ├── ActivityShape.module.scss │ │ │ ├── ActivityShape.tsx │ │ │ ├── DomainServiceEditor.module.scss │ │ │ ├── DomainServiceEditor.tsx │ │ │ ├── ExternalServiceEditor.tsx │ │ │ ├── ScenarioServiceSelect.module.scss │ │ │ ├── ScenarioServiceSelect.tsx │ │ │ ├── ShareIcon.tsx │ │ │ ├── activity.png │ │ │ ├── common.module.scss │ │ │ ├── index.tsx │ │ │ └── validate.ts │ │ │ ├── Comment │ │ │ ├── comment.png │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ │ ├── CommentEdge │ │ │ └── index.tsx │ │ │ ├── Decision │ │ │ ├── decision.png │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ │ ├── End │ │ │ ├── end.png │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ │ ├── LabelEdge │ │ │ ├── Label.module.scss │ │ │ ├── Label.tsx │ │ │ └── index.tsx │ │ │ ├── Lane │ │ │ ├── Lane.tsx │ │ │ ├── LaneShape.module.scss │ │ │ ├── LaneShape.tsx │ │ │ ├── constants.ts │ │ │ ├── index.tsx │ │ │ ├── register.tsx │ │ │ └── useLanesDrag.tsx │ │ │ ├── NormalEdge │ │ │ └── index.tsx │ │ │ ├── Start │ │ │ ├── TriangleIcon.tsx │ │ │ ├── index.module.scss │ │ │ ├── index.tsx │ │ │ └── start.png │ │ │ ├── index.tsx │ │ │ ├── shared.module.scss │ │ │ └── shared.ts │ └── service-design │ │ ├── factory.ts │ │ └── index.ts ├── session │ ├── README.md │ ├── api-helper.ts │ ├── api │ │ ├── device-check.ts │ │ ├── index.ts │ │ ├── ip-state.test.ts │ │ ├── ip-state.ts │ │ ├── login.ts │ │ ├── logout.ts │ │ ├── session.ts │ │ ├── update-entry.ts │ │ └── utils.ts │ ├── config.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useDeviceCheck.tsx │ │ ├── useLogout.ts │ │ └── useSession.ts │ ├── index.ts │ ├── middleware.ts │ ├── server.ts │ ├── ssr-helper.ts │ └── types.ts ├── storage │ ├── CacheContainer.test.ts │ ├── CacheContainer.ts │ ├── CacheStorageInLRUCache.test.ts │ ├── CacheStorageInLRUCache.ts │ ├── CacheStorageInMemory.test.ts │ ├── CacheStorageInMemory.ts │ ├── CacheStorageInRedis.test.ts │ ├── CacheStorageInRedis.ts │ ├── ICacheStorage.ts │ ├── index.ts │ └── utils.ts ├── system │ ├── Organization │ │ └── index.tsx │ ├── README.md │ ├── SystemLayout │ │ └── index.tsx │ ├── User │ │ ├── Create.tsx │ │ ├── Update.tsx │ │ ├── UserSelect.tsx │ │ └── index.tsx │ └── types.ts ├── team │ ├── App │ │ ├── Association │ │ │ ├── VersionSelect.tsx │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── Create.tsx │ │ ├── Doc │ │ │ ├── AppDocLayout.module.scss │ │ │ ├── AppDocLayout.tsx │ │ │ ├── Doc.tsx │ │ │ ├── Domain.tsx │ │ │ ├── Scenario.tsx │ │ │ └── index.tsx │ │ ├── Graph.tsx │ │ ├── Home.tsx │ │ ├── Reversion.tsx │ │ └── Update.tsx │ ├── Creator │ │ ├── index.module.scss │ │ └── index.tsx │ ├── Domain │ │ ├── ApiDoc │ │ │ ├── ApiDoc.tsx │ │ │ ├── ObjectCard.module.scss │ │ │ ├── ObjectCard.tsx │ │ │ ├── TypeRender.module.scss │ │ │ ├── TypeRender.tsx │ │ │ ├── TypescriptIcon.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── extra-api.test.ts.snap │ │ │ ├── extra-api.data.json │ │ │ ├── extra-api.test.ts │ │ │ ├── extra-api.ts │ │ │ ├── index.ts │ │ │ ├── typescript.test.ts │ │ │ └── typescript.ts │ │ ├── Create.tsx │ │ ├── Doc.module.scss │ │ ├── Doc.tsx │ │ ├── Graph.tsx │ │ ├── Home.tsx │ │ ├── Reversion.module.scss │ │ ├── Reversion.tsx │ │ ├── Update.tsx │ │ └── useStat.ts │ ├── README.md │ ├── Scenario │ │ ├── Create.tsx │ │ ├── Doc │ │ │ ├── ApiDoc.tsx │ │ │ └── index.tsx │ │ ├── Graph.tsx │ │ ├── Home.tsx │ │ ├── Reversion.module.scss │ │ ├── Reversion.tsx │ │ ├── Update.tsx │ │ └── useStat.ts │ ├── Team │ │ ├── index.module.scss │ │ ├── index.tsx │ │ └── useTeamInfo.ts │ ├── TeamLayout │ │ ├── AppIcon.tsx │ │ ├── Context.tsx │ │ ├── DomainIcon.tsx │ │ ├── FlowIcon.tsx │ │ ├── LanguageIcon.tsx │ │ ├── TeamIcon.tsx │ │ ├── TeamLayout.tsx │ │ ├── TeamLayoutModel.tsx │ │ └── index.tsx │ ├── UbiquitousLanguage │ │ ├── Language.tsx │ │ ├── LanguageModel.ts │ │ ├── OrganizationLanguage.tsx │ │ ├── README.md │ │ ├── TeamLanguage.tsx │ │ ├── types.ts │ │ └── useGlobalUbiquitousLanguage.ts │ ├── Updater │ │ └── index.tsx │ └── types.ts └── user │ ├── AccountSetting │ ├── BaseInfo.module.scss │ ├── BaseInfo.tsx │ ├── Invites.module.scss │ ├── Invites.tsx │ ├── ResetPassword.module.scss │ ├── ResetPassword.tsx │ ├── index.module.scss │ └── index.tsx │ ├── Launch │ ├── BotIcon.tsx │ ├── OrganizationIcon.tsx │ ├── SystemIcon.tsx │ ├── TeamIcon.tsx │ ├── VerifyPermission.tsx │ ├── index.module.scss │ ├── index.tsx │ ├── types.ts │ ├── useVerifyPermission.ts │ ├── utils.test.ts │ └── utils.ts │ ├── Login │ ├── Forgot.tsx │ ├── Layout.module.scss │ ├── Layout.tsx │ ├── Login.module.scss │ ├── Login.tsx │ ├── Register.module.scss │ ├── Register.tsx │ ├── ResetPassword.tsx │ ├── bg.jpeg │ └── index.tsx │ └── api │ ├── create-invite-code.ts │ ├── index.ts │ ├── invite-code.test.ts │ ├── invite-code.ts │ └── register.ts ├── next.config.js ├── package.json ├── pages ├── 403.tsx ├── 404.tsx ├── _app.tsx ├── _document.tsx ├── _error.tsx ├── api │ ├── README.md │ ├── create-invite-code.ts │ ├── device-check.ts │ ├── hello.ts │ ├── login.ts │ ├── logout.ts │ ├── register.ts │ ├── rest │ │ ├── ai │ │ │ ├── chat-supported.ts │ │ │ ├── dall-e.ts │ │ │ ├── data-object-builder.ts │ │ │ ├── data-object.ts │ │ │ ├── ddd-master.ts │ │ │ ├── echo.ts │ │ │ ├── extra-words.ts │ │ │ ├── fallback.ts │ │ │ ├── flow-builder.ts │ │ │ ├── free-usage.ts │ │ │ ├── models.ts │ │ │ ├── proxy.ts │ │ │ ├── sql-master.ts │ │ │ ├── subject.ts │ │ │ ├── summary.ts │ │ │ ├── vision.ts │ │ │ ├── wakeadmin-form.ts │ │ │ ├── wakeadmin-table.ts │ │ │ └── words-to-ubiquitous-language.ts │ │ ├── domain │ │ │ └── [id] │ │ │ │ ├── base64.ts │ │ │ │ ├── diff.ts │ │ │ │ ├── index.ts │ │ │ │ ├── v2.ts │ │ │ │ └── vector.ts │ │ ├── scenario │ │ │ └── [id] │ │ │ │ ├── base64.ts │ │ │ │ ├── diff.ts │ │ │ │ ├── index.ts │ │ │ │ ├── v2.ts │ │ │ │ └── vector.ts │ │ └── session.ts │ ├── session.ts │ └── update-entry.ts ├── chat.tsx ├── dashboard.tsx ├── doc │ ├── app │ │ └── [id] │ │ │ └── reversion │ │ │ └── [rid] │ │ │ ├── domain │ │ │ └── [did] │ │ │ │ └── reversion │ │ │ │ └── [drid].tsx │ │ │ ├── index.tsx │ │ │ └── scenario │ │ │ └── [sid] │ │ │ └── reversion │ │ │ └── [srid].tsx │ ├── domain │ │ └── [id] │ │ │ └── reversion │ │ │ └── [rid].tsx │ └── scenario │ │ └── [id] │ │ └── reversion │ │ └── [rid].tsx ├── forgot.tsx ├── index.tsx ├── launch.tsx ├── login.ts ├── organization │ └── [id].tsx ├── register.tsx ├── reset-password.tsx ├── sentry_sample_error.tsx ├── sentry_sample_server_error.tsx ├── system │ ├── index.tsx │ ├── organization │ │ └── index.tsx │ └── user │ │ └── index.tsx └── team │ └── [id] │ ├── app │ ├── [aid] │ │ ├── index.tsx │ │ └── reversion │ │ │ └── [rid] │ │ │ └── index.tsx │ └── index.tsx │ ├── domain │ ├── [did] │ │ ├── index.tsx │ │ └── reversion │ │ │ └── [rid] │ │ │ ├── [action].tsx │ │ │ └── index.tsx │ └── index.tsx │ ├── index.tsx │ ├── scenario │ ├── [sid] │ │ ├── index.tsx │ │ └── reversion │ │ │ └── [rid] │ │ │ ├── [action].tsx │ │ │ └── index.tsx │ └── index.tsx │ └── ubiquitous-language │ ├── index.tsx │ └── organization.tsx ├── pnpm-lock.yaml ├── postcss.config.js ├── public ├── excel-templates │ └── ubiquitous-language.xlsx ├── favicon.ico ├── logo.svg ├── monaco │ └── min │ │ └── vs │ │ ├── base │ │ ├── browser │ │ │ └── ui │ │ │ │ └── codicons │ │ │ │ └── codicon │ │ │ │ └── codicon.ttf │ │ ├── common │ │ │ └── worker │ │ │ │ ├── simpleWorker.nls.de.js │ │ │ │ ├── simpleWorker.nls.es.js │ │ │ │ ├── simpleWorker.nls.fr.js │ │ │ │ ├── simpleWorker.nls.it.js │ │ │ │ ├── simpleWorker.nls.ja.js │ │ │ │ ├── simpleWorker.nls.js │ │ │ │ ├── simpleWorker.nls.ko.js │ │ │ │ ├── simpleWorker.nls.ru.js │ │ │ │ ├── simpleWorker.nls.zh-cn.js │ │ │ │ └── simpleWorker.nls.zh-tw.js │ │ └── worker │ │ │ └── workerMain.js │ │ ├── basic-languages │ │ ├── abap │ │ │ └── abap.js │ │ ├── apex │ │ │ └── apex.js │ │ ├── azcli │ │ │ └── azcli.js │ │ ├── bat │ │ │ └── bat.js │ │ ├── bicep │ │ │ └── bicep.js │ │ ├── cameligo │ │ │ └── cameligo.js │ │ ├── clojure │ │ │ └── clojure.js │ │ ├── coffee │ │ │ └── coffee.js │ │ ├── cpp │ │ │ └── cpp.js │ │ ├── csharp │ │ │ └── csharp.js │ │ ├── csp │ │ │ └── csp.js │ │ ├── css │ │ │ └── css.js │ │ ├── cypher │ │ │ └── cypher.js │ │ ├── dart │ │ │ └── dart.js │ │ ├── dockerfile │ │ │ └── dockerfile.js │ │ ├── ecl │ │ │ └── ecl.js │ │ ├── elixir │ │ │ └── elixir.js │ │ ├── flow9 │ │ │ └── flow9.js │ │ ├── freemarker2 │ │ │ └── freemarker2.js │ │ ├── fsharp │ │ │ └── fsharp.js │ │ ├── go │ │ │ └── go.js │ │ ├── graphql │ │ │ └── graphql.js │ │ ├── handlebars │ │ │ └── handlebars.js │ │ ├── hcl │ │ │ └── hcl.js │ │ ├── html │ │ │ └── html.js │ │ ├── ini │ │ │ └── ini.js │ │ ├── java │ │ │ └── java.js │ │ ├── javascript │ │ │ └── javascript.js │ │ ├── julia │ │ │ └── julia.js │ │ ├── kotlin │ │ │ └── kotlin.js │ │ ├── less │ │ │ └── less.js │ │ ├── lexon │ │ │ └── lexon.js │ │ ├── liquid │ │ │ └── liquid.js │ │ ├── lua │ │ │ └── lua.js │ │ ├── m3 │ │ │ └── m3.js │ │ ├── markdown │ │ │ └── markdown.js │ │ ├── mips │ │ │ └── mips.js │ │ ├── msdax │ │ │ └── msdax.js │ │ ├── mysql │ │ │ └── mysql.js │ │ ├── objective-c │ │ │ └── objective-c.js │ │ ├── pascal │ │ │ └── pascal.js │ │ ├── pascaligo │ │ │ └── pascaligo.js │ │ ├── perl │ │ │ └── perl.js │ │ ├── pgsql │ │ │ └── pgsql.js │ │ ├── php │ │ │ └── php.js │ │ ├── pla │ │ │ └── pla.js │ │ ├── postiats │ │ │ └── postiats.js │ │ ├── powerquery │ │ │ └── powerquery.js │ │ ├── powershell │ │ │ └── powershell.js │ │ ├── protobuf │ │ │ └── protobuf.js │ │ ├── pug │ │ │ └── pug.js │ │ ├── python │ │ │ └── python.js │ │ ├── qsharp │ │ │ └── qsharp.js │ │ ├── r │ │ │ └── r.js │ │ ├── razor │ │ │ └── razor.js │ │ ├── redis │ │ │ └── redis.js │ │ ├── redshift │ │ │ └── redshift.js │ │ ├── restructuredtext │ │ │ └── restructuredtext.js │ │ ├── ruby │ │ │ └── ruby.js │ │ ├── rust │ │ │ └── rust.js │ │ ├── sb │ │ │ └── sb.js │ │ ├── scala │ │ │ └── scala.js │ │ ├── scheme │ │ │ └── scheme.js │ │ ├── scss │ │ │ └── scss.js │ │ ├── shell │ │ │ └── shell.js │ │ ├── solidity │ │ │ └── solidity.js │ │ ├── sophia │ │ │ └── sophia.js │ │ ├── sparql │ │ │ └── sparql.js │ │ ├── sql │ │ │ └── sql.js │ │ ├── st │ │ │ └── st.js │ │ ├── swift │ │ │ └── swift.js │ │ ├── systemverilog │ │ │ └── systemverilog.js │ │ ├── tcl │ │ │ └── tcl.js │ │ ├── twig │ │ │ └── twig.js │ │ ├── typescript │ │ │ └── typescript.js │ │ ├── vb │ │ │ └── vb.js │ │ ├── wgsl │ │ │ └── wgsl.js │ │ ├── xml │ │ │ └── xml.js │ │ └── yaml │ │ │ └── yaml.js │ │ ├── editor │ │ ├── editor.main.css │ │ ├── editor.main.js │ │ ├── editor.main.nls.de.js │ │ ├── editor.main.nls.es.js │ │ ├── editor.main.nls.fr.js │ │ ├── editor.main.nls.it.js │ │ ├── editor.main.nls.ja.js │ │ ├── editor.main.nls.js │ │ ├── editor.main.nls.ko.js │ │ ├── editor.main.nls.ru.js │ │ ├── editor.main.nls.zh-cn.js │ │ └── editor.main.nls.zh-tw.js │ │ ├── language │ │ ├── css │ │ │ ├── cssMode.js │ │ │ └── cssWorker.js │ │ ├── html │ │ │ ├── htmlMode.js │ │ │ └── htmlWorker.js │ │ ├── json │ │ │ ├── jsonMode.js │ │ │ └── jsonWorker.js │ │ └── typescript │ │ │ ├── tsMode.js │ │ │ └── tsWorker.js │ │ └── loader.js └── prompt.json ├── scripts ├── build-docker-free.sh ├── build-in-zadig.sh ├── build-publish-collab-server.js ├── build-publish-signaling.js ├── build.sh ├── docker-build-in-zadig.js ├── docker-build.js ├── docker-publish.js ├── package-lock.json ├── package.json └── shared.js ├── sentry.client.config.js ├── sentry.edge.config.js ├── sentry.server.config.js ├── signaling ├── .dockerignore ├── Dockerfile ├── README.md ├── package.json └── pnpm-lock.yaml ├── styles ├── globals.css ├── markdown.scss ├── override.css └── theme.css ├── tailwind.config.js └── tsconfig.json /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | Dockerfile.tpl 3 | .dockerignore 4 | node_modules 5 | npm-debug.log 6 | README.md 7 | .next 8 | .git 9 | .swc 10 | .husky 11 | .vscode 12 | .sentryclirc 13 | .env.local 14 | embedding-index 15 | prompts 16 | scripts 17 | signaling 18 | tsconfig.tsbuildinfo 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | # 注意和 prettier-config-wk 保持一致 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | quote_type = single 12 | end_of_line = lf 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | build 3 | coverage 4 | node_modules 5 | public 6 | *.min.js -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals", 3 | "rules": { 4 | "no-shadow": "warn" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.png binary 3 | *.jpeg binary 4 | *.jpg binary 5 | *.doc binary 6 | *.docx binary -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run local-check -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com 2 | @wakeadmin:registry=https://registry.npmjs.org 3 | sharp_binary_host=https://npmmirror.com/mirrors/sharp 4 | sharp_libvips_binary_host=https://npmmirror.com/mirrors/sharp-libvips 5 | sentrycli_cdnurl=https://cdn.npmmirror.com/binaries/sentry-cli -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | build 3 | coverage 4 | node_modules 5 | public 6 | *.min.js 7 | 8 | .github/workflows/** -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - AI 搜索引擎集成? 2 | - 增量技术预研 3 | - 画图技术研究 4 | - 对象存储 5 | - sentry 设置用户名 6 | - IP 限制 -------------------------------------------------------------------------------- /browser-test/Dockerfile: -------------------------------------------------------------------------------- 1 | # 旧浏览器测试 2 | # 基于 sitespeed.io 提供的浏览器镜像进行测试 3 | FROM docker.io/sitespeedio/webbrowsers:chrome-70-firefox-62 4 | 5 | WORKDIR /root 6 | 7 | COPY ./entry.sh ./ 8 | 9 | EXPOSE 5900 10 | 11 | CMD bash /root/entry.sh 12 | -------------------------------------------------------------------------------- /browser-test/README.md: -------------------------------------------------------------------------------- 1 | # 旧浏览器测试 2 | 3 | ```shell 4 | docker build -t old-chrome . 5 | docker run -it --rm -p 5900:5900 old-chrome 6 | ``` 7 | 8 | 使用 VNC 客户端连接即可 9 | -------------------------------------------------------------------------------- /browser-test/entry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | # 启动 xvfb 6 | Xvfb :99 -screen 0 1980x1024x24 & 7 | 8 | export DISPLAY=:99 9 | 10 | # 运行 chrome 11 | google-chrome --no-sandbox & 12 | 13 | # 无密码运行 x11vnc 14 | x11vnc -forever 15 | 16 | # 运行 vnc://0.0.0.0:5900 17 | -------------------------------------------------------------------------------- /collab-server/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /collab-server/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com -------------------------------------------------------------------------------- /collab-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:19-alpine AS base 2 | 3 | # 第一步 安装依赖 4 | FROM base AS deps 5 | RUN apk add --no-cache libc6-compat 6 | WORKDIR /app 7 | COPY package.json .npmrc pnpm-lock.yaml* ./ 8 | RUN npm i -g pnpm@7 && pnpm install && ls 9 | 10 | 11 | # 第二步运行 12 | FROM base as runner 13 | 14 | ENV NODE_ENV production 15 | RUN addgroup --system --gid 1001 nodejs 16 | RUN adduser --system --uid 1001 nextjs 17 | 18 | WORKDIR /app 19 | 20 | COPY --from=deps --chown=nextjs:nodejs /app/ ./ 21 | COPY --chown=nextjs:nodejs ./index.mjs . 22 | 23 | USER nextjs 24 | 25 | EXPOSE 9090 26 | 27 | CMD ["node", "index.mjs"] 28 | -------------------------------------------------------------------------------- /collab-server/README.md: -------------------------------------------------------------------------------- 1 | # 多人协作 websocket 服务器 2 | 3 | # Build 4 | 5 | ```shell 6 | $ docker build -t wkfe/visual-ddd-collab --platform linux/amd64 . 7 | 8 | # 打版本 9 | $ docker tag wkfe/visual-ddd-collab 作用域/wkfe/visual-ddd-collab:版本号或latest 10 | 11 | # 推送 12 | $ docker push 作用域/wkfe/visual-ddd-collab:版本号或latest 13 | ``` 14 | 15 | # Run 16 | 17 | 暴露 9090 端口 18 | 19 | # 支持环境变量 20 | 21 | - MAIN_SERVER 主服务器入口地址, 比如 https://ddd.wakedt.cn 22 | -------------------------------------------------------------------------------- /collab-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "collab-server", 3 | "version": "1.0.0", 4 | "description": "多人协作服务器", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@hocuspocus/extension-logger": "^2.0.3", 14 | "@hocuspocus/server": "^2.0.3", 15 | "yjs": "^13.5.52" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /deployment/source/certbot-verify.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | 5 | # 配置http验证可访问 6 | location /.well-known/acme-challenge/ { 7 | root /usr/share/certbot/www; 8 | } 9 | } -------------------------------------------------------------------------------- /deployment/source/docker-compose-prepare-dev.yml: -------------------------------------------------------------------------------- 1 | # 用于一些准备工作,比如证书生成 2 | # 启动 docker compose up certbot 3 | version: '3.9' 4 | services: 5 | # 自签名证书生成 6 | # https://www.cnblogs.com/vishun/p/15746849.html 7 | mkcert: 8 | image: aegypius/mkcert-for-nginx-proxy 9 | volumes: 10 | # 证书文件存放位置 11 | - ./certbot/ssl:/data 12 | command: sh -c "mkdir -p /data/live/<%= DOMAIN %> && mkcert -cert-file /data/live/<%= DOMAIN %>/fullchain.pem -key-file /data/live/<%= DOMAIN %>/private.pem <%= DOMAIN %>" 13 | -------------------------------------------------------------------------------- /deployment/variable.sample.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | // 域名 3 | "DOMAIN": "hello.com", 4 | // 邮箱,主要用于证书生成 5 | "EMAIL": "邮箱", 6 | // 密钥,用于绘画生成 7 | "SECRET": "密钥(50个字符)" 8 | // 其余内容在生成后修改 docker-compose.yml 9 | } 10 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | declare interface Window { 2 | monaco: typeof import('monaco-editor'); 3 | } 4 | declare const monaco: typeof import('monaco-editor'); 5 | -------------------------------------------------------------------------------- /generator-demo/README.md: -------------------------------------------------------------------------------- 1 | # 增量生成器 DEMO 2 | 3 | TODO: 计划中 4 | 5 | POC 6 | 7 | 技术选型 8 | 9 | - [babel](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-validators), [Doc](https://babeljs.io/docs/babel-traverse) 10 | - [jscodeshift](https://github.com/facebook/jscodeshift) 11 | - [recast](https://github.com/benjamn/recast) 打印 12 | 13 | Other resource 14 | 15 | - https://assets.ctfassets.net/nn534z2fqr9f/3bytbtRUOWLkWugqGgn174/18fa7bf319ac168a5aa7644747a30bfb/Babel__A_refactoring_tool.pdf 16 | -------------------------------------------------------------------------------- /jest.env.js: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import { webcrypto } from 'node:crypto'; 3 | import { TextDecoder, TextEncoder } from 'util'; 4 | 5 | globalThis.crypto = webcrypto; 6 | globalThis.TextEncoder = TextEncoder; 7 | globalThis.TextDecoder = TextDecoder; 8 | -------------------------------------------------------------------------------- /lib/ai-directive-parser/exceptions.ts: -------------------------------------------------------------------------------- 1 | export class AITransformerParseError extends Error { 2 | static isAITransformerParseError(error: any): error is AITransformerParseError { 3 | return error && error instanceof AITransformerParseError; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/ai-directive-parser/index.ts: -------------------------------------------------------------------------------- 1 | export * from './parser'; 2 | export * from './exceptions'; 3 | -------------------------------------------------------------------------------- /lib/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from './method'; 2 | -------------------------------------------------------------------------------- /lib/api/method.ts: -------------------------------------------------------------------------------- 1 | import { NextApiHandler } from 'next'; 2 | 3 | export function allowMethod(method: 'GET' | 'POST' | 'PUT' | 'DELETE', handler: NextApiHandler): NextApiHandler { 4 | return (req, res) => { 5 | if (req.method !== method) { 6 | res.status(405).end(); 7 | } else { 8 | return handler(req, res); 9 | } 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /lib/chat-bot/BotSessionStoreEvent.ts: -------------------------------------------------------------------------------- 1 | import { EventBus, EventsWithArg, EventsWithoutArg } from '@/lib/utils'; 2 | 3 | /** 4 | * 会话存储事件 5 | */ 6 | export interface BotSessionStoreEventDefinitions { 7 | /** 8 | * 会话变动 9 | */ 10 | SESSION_CHANGE: { sessionId: string }; 11 | } 12 | 13 | export type BotSessionStoreEventsWithoutArg = EventsWithoutArg; 14 | 15 | export type BotSessionStoreEventsWithArg = EventsWithArg; 16 | 17 | export class BotSessionStoreEvent extends EventBus {} 18 | -------------------------------------------------------------------------------- /lib/chat-bot/BotWindowEvent.ts: -------------------------------------------------------------------------------- 1 | import { EventBus, EventsWithArg, EventsWithoutArg } from '@/lib/utils'; 2 | 3 | /** 4 | * 聊天窗口事件 5 | */ 6 | export interface BotWindowEventDefinitions { 7 | /** 8 | * 显示聊天窗 9 | */ 10 | SHOW: never; 11 | 12 | /** 13 | * 尺寸变化 14 | */ 15 | SIZE_CHANGE: { size: number }; 16 | } 17 | 18 | export type BotWindowEventsWithoutArg = EventsWithoutArg; 19 | 20 | export type BotWindowEventsWithArg = EventsWithArg; 21 | 22 | export class BotWindowEvent extends EventBus {} 23 | -------------------------------------------------------------------------------- /lib/chat-bot/ChatPage/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './ChatPage'; 2 | -------------------------------------------------------------------------------- /lib/chat-bot/ChatPage/robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/lib/chat-bot/ChatPage/robot.png -------------------------------------------------------------------------------- /lib/chat-bot/ChatWindow/StopIcon.tsx: -------------------------------------------------------------------------------- 1 | export const StopIcon = (props: React.SVGAttributes) => { 2 | return ( 3 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /lib/chat-bot/ChatWindow/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './ChatWindow'; 2 | -------------------------------------------------------------------------------- /lib/chat-bot/PromptLibrary/Modal.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | height: 85vh; 3 | overflow: hidden; 4 | 5 | :global { 6 | .ant-modal-content { 7 | height: 100%; 8 | padding: 0; 9 | overflow: hidden; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/chat-bot/PromptLibrary/README.md: -------------------------------------------------------------------------------- 1 | # prompt 库 2 | -------------------------------------------------------------------------------- /lib/chat-bot/PromptLibrary/index.tsx: -------------------------------------------------------------------------------- 1 | export { Modal as PromptLibraryModal } from './Modal'; 2 | -------------------------------------------------------------------------------- /lib/chat-bot/PromptLibrary/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/lib/chat-bot/PromptLibrary/types.ts -------------------------------------------------------------------------------- /lib/chat-bot/README.md: -------------------------------------------------------------------------------- 1 | # 聊天机器人 2 | -------------------------------------------------------------------------------- /lib/chat-bot/extensions/index.ts: -------------------------------------------------------------------------------- 1 | // 内置指令 2 | import './list'; 3 | import './clear'; 4 | import './bug'; 5 | -------------------------------------------------------------------------------- /lib/chat-bot/index.tsx: -------------------------------------------------------------------------------- 1 | import './extensions'; 2 | 3 | export * from './ChatWindow'; 4 | export * from './ChatPage'; 5 | export * from './protocol'; 6 | export * from './BotModel'; 7 | export * from './registry'; 8 | export * from './constants'; 9 | export * from './helpers'; 10 | -------------------------------------------------------------------------------- /lib/chat-bot/util.ts: -------------------------------------------------------------------------------- 1 | const MENTION_REGEX = /^#([^\s#]+)/; 2 | 3 | /** 4 | * 从字符串中提取插件 ID 5 | * @param str 6 | * @returns 7 | */ 8 | export function extraMention(str: string) { 9 | if (str.charAt(0) !== '#') { 10 | return null; 11 | } 12 | 13 | const matched = str.match(MENTION_REGEX); 14 | if (matched) { 15 | return matched[1]; 16 | } 17 | 18 | return null; 19 | } 20 | -------------------------------------------------------------------------------- /lib/chat-bot/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { extraMention } from './util'; 2 | 3 | describe('extraMention', () => { 4 | it('should return the extra mention', () => { 5 | expect(extraMention('#world#')).toBe('world'); 6 | expect(extraMention('#world ')).toBe('world'); 7 | expect(extraMention('#world#hello ')).toBe('world'); 8 | expect(extraMention('world#hello ')).toBe(null); 9 | expect(extraMention('world#hello# ')).toBe(null); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /lib/components/ColorInput/ColorPalette.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 225px; 3 | 4 | :global(.chrome-picker) { 5 | box-shadow: none !important; 6 | } 7 | 8 | :global(.sketch-picker) { 9 | box-shadow: none !important; 10 | width: 100% !important; 11 | padding: 0 !important; 12 | } 13 | } 14 | 15 | .history { 16 | margin-top: var(--vd-spacing-xs); 17 | } 18 | 19 | .colorListName { 20 | font-size: var(--vd-font-size-h6); 21 | color: var(--vd-color-font-regular); 22 | } 23 | 24 | .colorList { 25 | width: 100%; 26 | display: flex; 27 | } 28 | 29 | .colorItem { 30 | width: 28px; 31 | height: 28px; 32 | } 33 | -------------------------------------------------------------------------------- /lib/components/ColorInput/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | } 3 | 4 | .preview { 5 | width: 18px; 6 | height: 18px; 7 | border-radius: 3px; 8 | background: white; 9 | border: 1px solid #e6e6e6; 10 | margin-left: -5px; 11 | } 12 | 13 | .popover { 14 | :global(.ant-popover-inner-content) { 15 | padding: 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/components/Completion/Completion.tsx: -------------------------------------------------------------------------------- 1 | import { NameCase } from '@/lib/core'; 2 | import { NoopArray } from '@wakeapp/utils'; 3 | import { useCompletionContext } from './CompletionContext'; 4 | 5 | export function useIdentifierCompletion(wordCase: NameCase) { 6 | const context = useCompletionContext(); 7 | 8 | return (value: string) => context?.getCompletion(wordCase).search(value) ?? NoopArray; 9 | } 10 | 11 | export function useCompletion() { 12 | const context = useCompletionContext(); 13 | 14 | return (value: string) => context?.getCompletion('any').search(value) ?? NoopArray; 15 | } 16 | -------------------------------------------------------------------------------- /lib/components/Completion/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 自动推断 3 | */ 4 | export * from './Completion'; 5 | export * from './CompletionContext'; 6 | -------------------------------------------------------------------------------- /lib/components/Completion/type.ts: -------------------------------------------------------------------------------- 1 | import { NameCase } from '@/lib/core'; 2 | import { CompletionImplement } from './CompletionImplement'; 3 | 4 | export interface CompletionContextValue { 5 | /** 6 | * 所有单词 7 | */ 8 | words: string[]; 9 | 10 | /** 11 | * 有效的标识符 12 | */ 13 | identifiers: string[]; 14 | 15 | getCompletion: (key: NameCase | 'any') => CompletionImplement; 16 | } 17 | -------------------------------------------------------------------------------- /lib/components/DescriptionInput/index.tsx: -------------------------------------------------------------------------------- 1 | import { Input } from 'antd'; 2 | import type { TextAreaProps } from 'antd/es/input/TextArea'; 3 | 4 | export interface DescriptionInputProps extends TextAreaProps {} 5 | 6 | const AUTO_SIZE = { minRows: 3, maxRows: 8 }; 7 | 8 | export const DescriptionInput = (props: DescriptionInputProps) => { 9 | return ; 10 | }; 11 | -------------------------------------------------------------------------------- /lib/components/FullScreenContainer/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: relative; 3 | background-color: white; 4 | } 5 | 6 | .icon { 7 | position: absolute; 8 | right: 4px; 9 | top: 4px; 10 | line-height: 1; 11 | border-radius: 4px; 12 | cursor: pointer; 13 | font-size: 18px; 14 | padding: 5px; 15 | background-color: rgba(255, 255, 255, 0.9); 16 | color: gray; 17 | z-index: 1; 18 | 19 | &:hover { 20 | color: black; 21 | background-color: rgb(216, 216, 216); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/components/Import/index.module.scss: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-size: 40px; 3 | color: var(--vd-color-primary); 4 | margin-bottom: 8px; 5 | } 6 | -------------------------------------------------------------------------------- /lib/components/Mermaid/Container.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 100%; 3 | height: 100%; 4 | overflow: hidden; 5 | } 6 | -------------------------------------------------------------------------------- /lib/components/Mermaid/MindMap.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react'; 2 | import { MermaidComponent } from './MermaidComponent'; 3 | 4 | import { MindMapNode } from './types'; 5 | import { mindMapNodeToMermaidCode } from './utils'; 6 | 7 | export interface MindMapProps extends React.HTMLAttributes { 8 | tree: MindMapNode; 9 | } 10 | 11 | /** 12 | * 思维导图渲染 13 | * @param props 14 | * @returns 15 | */ 16 | export const MindMap = (props: MindMapProps) => { 17 | const { tree, ...other } = props; 18 | const code = useMemo(() => mindMapNodeToMermaidCode(tree), [tree]); 19 | 20 | return ; 21 | }; 22 | -------------------------------------------------------------------------------- /lib/components/Mermaid/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MermaidComponent'; 2 | export * from './MindMap'; 3 | export * from './Container'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /lib/components/Mermaid/types.ts: -------------------------------------------------------------------------------- 1 | export type MindMapNodeShape = 'square' | 'rounded-square' | 'circle' | 'bang' | 'cloud' | 'hexagon' | 'default'; 2 | export interface MindMapNode { 3 | name: string; 4 | /** 5 | * 外形,默认 default 6 | */ 7 | shape?: MindMapNodeShape; 8 | children?: MindMapNode[]; 9 | } 10 | -------------------------------------------------------------------------------- /lib/components/NameInput/index.module.scss: -------------------------------------------------------------------------------- 1 | .match { 2 | margin-top: var(--vd-spacing-xs); 3 | align-items: flex-start; 4 | padding: 4px 6px; 5 | user-select: none; 6 | } 7 | 8 | .matchBody { 9 | font-size: var(--vd-font-size-h6); 10 | } 11 | 12 | .matchContent { 13 | margin-top: var(--vd-spacing-xs); 14 | } 15 | 16 | .matchList { 17 | padding: 0; 18 | margin: 0; 19 | list-style: none; 20 | } 21 | -------------------------------------------------------------------------------- /lib/components/Prompt/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global { 3 | .ant-modal-confirm-btns { 4 | margin-top: 40px; 5 | text-align: center; 6 | } 7 | 8 | .ant-modal-confirm-content { 9 | margin-inline-start: 0 !important; 10 | max-width: unset !important; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/components/SortableList/index.module.scss: -------------------------------------------------------------------------------- 1 | .handle { 2 | cursor: grab; 3 | padding: 0 4px; 4 | font-size: 14px; 5 | } 6 | 7 | .dragging { 8 | z-index: var(--vd-z-index-tooltip); 9 | } 10 | -------------------------------------------------------------------------------- /lib/components/Title/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | 3 | export interface TitleProps { 4 | children?: string; 5 | } 6 | 7 | export const Title = (props: TitleProps) => { 8 | const { children } = props; 9 | 10 | return ( 11 | 12 | {`${children} - Visual DDD`} 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /lib/components/UbiquitousLanguageCompletion/README.md: -------------------------------------------------------------------------------- 1 | # 统一语言候选推断 2 | -------------------------------------------------------------------------------- /lib/components/UbiquitousLanguageCompletion/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Context'; 2 | -------------------------------------------------------------------------------- /lib/components/VersionBadge/index.module.scss: -------------------------------------------------------------------------------- 1 | .root:global(.block) { 2 | display: inline-flex; 3 | color: white; 4 | font-size: 12px; 5 | height: 20px; 6 | line-height: 20px; 7 | padding: 0 6px; 8 | border-radius: 2px; 9 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); 10 | vertical-align: middle; 11 | background-color: var(--color); 12 | } 13 | 14 | .root:global(.text) { 15 | color: var(--color); 16 | display: inline-block; 17 | } 18 | 19 | .version { 20 | font-weight: bold; 21 | } 22 | 23 | .status { 24 | margin-left: var(--vd-spacing-xs); 25 | color: var(--vd-color-gray-400); 26 | } 27 | -------------------------------------------------------------------------------- /lib/components/VersionControl/README.md: -------------------------------------------------------------------------------- 1 | # 版本控制 2 | -------------------------------------------------------------------------------- /lib/components/VersionControl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './VersionList'; 2 | export * from './VersionCreate'; 3 | export * from './VersionPublish'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /lib/components/VersionControl/types.ts: -------------------------------------------------------------------------------- 1 | import { VersionStatus } from '@/lib/core'; 2 | 3 | export { VersionStatus }; 4 | 5 | export interface IVersion { 6 | id: number; 7 | createTime: string; 8 | createBy: string; 9 | startVersion: string; 10 | currentVersion: string; 11 | description: string; 12 | state: VersionStatus; 13 | } 14 | 15 | export interface VersionCreatePayload { 16 | startVersionId: number; 17 | startVersion: string; 18 | currentVersion: string; 19 | description: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/contants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './keybinding'; 2 | -------------------------------------------------------------------------------- /lib/contants/keybinding.ts: -------------------------------------------------------------------------------- 1 | export const OTHER_KEY_MAP: Record = { 2 | plus: '+', 3 | }; 4 | 5 | export const MAC_OS_KEY_MAP: Record = { 6 | command: '⌘', 7 | alt: '⌥', 8 | plus: '+', 9 | option: '⌥', 10 | ctrl: '⌃', 11 | shift: '⇧', 12 | }; 13 | -------------------------------------------------------------------------------- /lib/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './constants'; 3 | -------------------------------------------------------------------------------- /lib/designer/IDesigner.ts: -------------------------------------------------------------------------------- 1 | export interface IDesigner { 2 | /** 3 | * 保存 4 | */ 5 | save(): Promise; 6 | } 7 | -------------------------------------------------------------------------------- /lib/designer/IDesignerTab.ts: -------------------------------------------------------------------------------- 1 | export interface IDesignerTab { 2 | /** 3 | * 激活 4 | * @returns 5 | */ 6 | active: () => void; 7 | 8 | /** 9 | * 数据验证, 返回 true 表示验证不通过 10 | */ 11 | validate: () => Promise; 12 | 13 | /** 14 | * 清空 undo 栈 15 | * 因为数据加载后,会自动添加一个栈 16 | * @returns 17 | */ 18 | clearUndoStack: () => void; 19 | } 20 | -------------------------------------------------------------------------------- /lib/designer/components/DesignerLayout/Loading/index.module.scss: -------------------------------------------------------------------------------- 1 | .mask { 2 | position: fixed; 3 | left: 0; 4 | right: 0; 5 | top: 0; 6 | bottom: 0; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | backdrop-filter: blur(3px); 11 | z-index: 100; 12 | } 13 | 14 | .root { 15 | background: white; 16 | padding: 46px; 17 | border-radius: 10px; 18 | } 19 | -------------------------------------------------------------------------------- /lib/designer/components/DesignerLayout/Loading/index.tsx: -------------------------------------------------------------------------------- 1 | import { Spin } from 'antd'; 2 | 3 | import s from './index.module.scss'; 4 | 5 | export interface DesignerLoadingProps { 6 | loading?: boolean; 7 | } 8 | 9 | export const DesignerLoading = (props: DesignerLoadingProps) => { 10 | const { loading } = props; 11 | 12 | if (!loading) { 13 | return null; 14 | } 15 | 16 | return ( 17 |
18 |
19 | 20 |
21 |
22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /lib/designer/components/DesignerLayout/README.md: -------------------------------------------------------------------------------- 1 | TODO: 放到 designer 模块中 2 | 3 | # 设计器布局 4 | -------------------------------------------------------------------------------- /lib/designer/components/DesignerLayout/TabLabel/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding-right: 0.5em; 3 | :global(.anticon) { 4 | position: absolute; 5 | font-size: 0.8em; 6 | top: 50%; 7 | transform: translateY(-50%); 8 | right: -1.5em; 9 | } 10 | 11 | &:global(.error .anticon) { 12 | color: var(--vd-color-danger-300); 13 | } 14 | 15 | &:global(.warning .anticon) { 16 | color: var(--vd-color-warning-300); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/designer/components/DesignerLayout/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './Header'; 2 | export * from './Loading'; 3 | export * from './Layout'; 4 | export * from './TabLabel'; 5 | -------------------------------------------------------------------------------- /lib/designer/components/DiffView.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: var(--vd-spacing-sm) 0; 3 | height: 50vh; 4 | } 5 | 6 | .editor { 7 | height: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /lib/designer/components/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './HistoryViewModal'; 2 | export * from './DesignerLayout'; 3 | -------------------------------------------------------------------------------- /lib/designer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BaseDesignerModel'; 2 | export * from './DesignerKeyboardBinding'; 3 | export * from './IDesigner'; 4 | export * from './IDesignerTab'; 5 | export * from './DesignerAwareness'; 6 | export * from './BaseDesignerContext'; 7 | export * from './components'; 8 | -------------------------------------------------------------------------------- /lib/dom/index.ts: -------------------------------------------------------------------------------- 1 | export function scrollIntoView(select: string) { 2 | const element = document.querySelector(select); 3 | if (element) { 4 | element.scrollIntoView({ behavior: 'smooth' }); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /lib/editor/Canvas/CanvasEvent.ts: -------------------------------------------------------------------------------- 1 | import { EventBus, EventsWithArg, EventsWithoutArg } from '@/lib/utils'; 2 | 3 | /** 4 | * 画布事件 5 | */ 6 | export interface CanvasEventDefinitions { 7 | /** 8 | * 可见性变动 9 | */ 10 | NODE_VISIBLE_CHANGE: { id: string; visible: boolean }; 11 | } 12 | 13 | export type CanvasEventsWithoutArg = EventsWithoutArg; 14 | 15 | export type CanvasEventsWithArg = EventsWithArg; 16 | 17 | export class CanvasEvent extends EventBus {} 18 | -------------------------------------------------------------------------------- /lib/editor/Canvas/Cells.tsx: -------------------------------------------------------------------------------- 1 | import { observer } from 'mobx-react'; 2 | import { useEditorModel } from '../Model'; 3 | import { ShapeRenderer } from '../Shape'; 4 | 5 | /** 6 | * 节点渲染 7 | */ 8 | export const Cells = observer(function Cells() { 9 | const { store } = useEditorModel(); 10 | 11 | return ( 12 | <> 13 | {store?.nodes.map(node => { 14 | return ; 15 | })} 16 | 17 | ); 18 | }); 19 | -------------------------------------------------------------------------------- /lib/editor/Canvas/ContextMenu.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | z-index: 1000; 6 | } 7 | 8 | .danger { 9 | :global(.x6-menu-item-text) { 10 | color: var(--vd-color-danger); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/editor/Canvas/README.md: -------------------------------------------------------------------------------- 1 | # 画布 2 | -------------------------------------------------------------------------------- /lib/editor/Canvas/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Canvas'; 2 | export * from './CanvasEvent'; 3 | export * from './CanvasModel'; 4 | export * from './CanvasModelContext'; 5 | export type { CopyPayload } from './ClipboardUtils'; 6 | export type { 7 | EditorContextMenuItem, 8 | EditorContextMenuContext, 9 | EditorContextMenuDivider, 10 | EditorContextMenu, 11 | } from './ContextMenuController'; 12 | -------------------------------------------------------------------------------- /lib/editor/Model/FormModel/constants.ts: -------------------------------------------------------------------------------- 1 | export const ROOT_FIELD = '__ROOT__'; 2 | -------------------------------------------------------------------------------- /lib/editor/Model/FormModel/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FormModel'; 2 | export * from './types'; 3 | export * from './constants'; 4 | -------------------------------------------------------------------------------- /lib/editor/Model/README.md: -------------------------------------------------------------------------------- 1 | # 模型层 2 | 3 | 这里不会包含任何 UI 层内容,只维护状态 4 | 5 | - Model 入口,管理者,会维护 effects 6 | - Store 核心状态 7 | - Datasource 持久化数据源 8 | - Event 事件总线 9 | - Index 索引信息,只要用于加速计算。这里的信息通过事件监听生成,不会直接依赖其他对象 10 | - CommandHandler 暴露为 View 层的命令 11 | -------------------------------------------------------------------------------- /lib/editor/Model/Yjs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './NodeYMap'; 2 | export { buildEditorYjs, buildEmptyEditorYjs } from './Builder'; 3 | export type { EditorYjsBuilder } from './Builder'; 4 | -------------------------------------------------------------------------------- /lib/editor/Model/constants.ts: -------------------------------------------------------------------------------- 1 | export const ROOT_ID = '__ROOT__'; 2 | -------------------------------------------------------------------------------- /lib/editor/Model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './FormModel'; 3 | export * from './BaseNode'; 4 | export * from './BaseEditorStore'; 5 | export * from './BaseEditorViewStore'; 6 | export * from './BaseEditorFormStore'; 7 | export * from './EditorModelContext'; 8 | export * from './BaseEditorCommandHandler'; 9 | export * from './BaseEditorModel'; 10 | export * from './BaseEditorEvent'; 11 | export * from './BaseEditorScope'; 12 | export * from './BaseEditorValidateManager'; 13 | export * from './BaseEditorPropertyLocationObserver'; 14 | -------------------------------------------------------------------------------- /lib/editor/Model/mapper.ts: -------------------------------------------------------------------------------- 1 | import { toJS } from 'mobx'; 2 | import { BaseNode } from './BaseNode'; 3 | import { NodePO } from './types'; 4 | 5 | /** 6 | * 转换为持久化对象 7 | */ 8 | export function toNodePO(node: BaseNode): NodePO { 9 | return { 10 | id: node.id, 11 | parent: node.parent?.id, 12 | children: node.children.map(n => n.id), 13 | properties: toJS(node.properties), 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /lib/editor/Shape/builtin/README.md: -------------------------------------------------------------------------------- 1 | # 内置外形 2 | -------------------------------------------------------------------------------- /lib/editor/Shape/builtin/activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/lib/editor/Shape/builtin/activity.png -------------------------------------------------------------------------------- /lib/editor/Shape/builtin/comment.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | background-color: #fffbe7; 3 | width: 100%; 4 | height: 100%; 5 | overflow: auto; 6 | padding: var(--vd-spacing-xs); 7 | box-shadow: 1px 0px 13px -2px #c7c7c7; 8 | font-size: var(--vd-font-size-h5); 9 | white-space: pre-wrap; 10 | } 11 | -------------------------------------------------------------------------------- /lib/editor/Shape/builtin/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/lib/editor/Shape/builtin/comment.png -------------------------------------------------------------------------------- /lib/editor/Shape/builtin/constants.ts: -------------------------------------------------------------------------------- 1 | export enum BuiltinShapeName { 2 | Activity = 'activity', 3 | Comment = 'comment', 4 | Edge = 'edge', 5 | } 6 | -------------------------------------------------------------------------------- /lib/editor/Shape/builtin/index.ts: -------------------------------------------------------------------------------- 1 | import './edge'; 2 | import './activity'; 3 | import './comment'; 4 | export * from './constants'; 5 | -------------------------------------------------------------------------------- /lib/editor/Shape/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_AUTO_RESIZE_GROUP_PADDING = 30; 2 | -------------------------------------------------------------------------------- /lib/editor/Shape/defineShape.ts: -------------------------------------------------------------------------------- 1 | import { ShapeConfiguration } from './types'; 2 | import { shapes } from './store'; 3 | 4 | /** 5 | * 定义图形组件 6 | * @param name 组件名称,必须全局唯一 7 | */ 8 | export function defineShape(configuration: ShapeConfiguration) { 9 | const name = configuration.name; 10 | if (shapes.has(name)) { 11 | throw new Error(`defineShape ${name} already defined`); 12 | } 13 | 14 | shapes.set(name, configuration); 15 | } 16 | -------------------------------------------------------------------------------- /lib/editor/Shape/hooks/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 这里定义一些常用的 Hooks, 方便组件创建 3 | */ 4 | export * from './useHoverShowPorts'; 5 | export * from './useShapeModel'; 6 | -------------------------------------------------------------------------------- /lib/editor/Shape/index.ts: -------------------------------------------------------------------------------- 1 | import './react-component-decorators'; 2 | 3 | export * from './builtin'; 4 | export * from './types'; 5 | export * from './ShapeRegistry'; 6 | export * from './defineShape'; 7 | export * from './ShapeRenderer'; 8 | export * from './utils'; 9 | export * from './hooks'; 10 | export { getShape, getValidator } from './store'; 11 | -------------------------------------------------------------------------------- /lib/editor/Shape/react-component-decorators/FormStatus.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | --color: var(--vd-color-warning-400); 3 | position: absolute; 4 | pointer-events: none; 5 | width: 100%; 6 | height: 100%; 7 | // border: 1px solid var(--color); 8 | outline: 1px solid var(--color); 9 | z-index: 3; 10 | border-radius: 8px; 11 | 12 | &:global(.error) { 13 | --color: var(--vd-color-danger-400); 14 | } 15 | 16 | :global(.anticon) { 17 | color: var(--color); 18 | margin: 2px; 19 | cursor: context-menu; 20 | pointer-events: auto; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/editor/Shape/react-component-decorators/Observer.tsx: -------------------------------------------------------------------------------- 1 | import { ReactDecorator } from '@/lib/g6-binding'; 2 | import { observer } from 'mobx-react'; 3 | 4 | /** 5 | * 支持 mobx 数据响应式 6 | */ 7 | export const ObserverDecorator: ReactDecorator = Input => { 8 | return observer(Input); 9 | }; 10 | -------------------------------------------------------------------------------- /lib/editor/Shape/react-component-decorators/README.md: -------------------------------------------------------------------------------- 1 | # React 组件装饰器 2 | -------------------------------------------------------------------------------- /lib/editor/Shape/react-component-decorators/index.ts: -------------------------------------------------------------------------------- 1 | import { registerReactDecorator } from '@/lib/g6-binding'; 2 | import { ObserverDecorator } from './Observer'; 3 | import { AutoResizeDecorator } from './AutoResize'; 4 | import { FormStatus } from './FormStatus'; 5 | 6 | registerReactDecorator('Observer', ObserverDecorator); 7 | registerReactDecorator('FormStatus', FormStatus); 8 | registerReactDecorator('AutoResize', AutoResizeDecorator); 9 | -------------------------------------------------------------------------------- /lib/editor/Shape/utils.ts: -------------------------------------------------------------------------------- 1 | import isObject from 'lodash/isObject'; 2 | 3 | import { ShapeCoreInfo } from './types'; 4 | 5 | export function assertShapeInfo(data: any): data is ShapeCoreInfo { 6 | return isObject(data) && (data as any).type != null; 7 | } 8 | -------------------------------------------------------------------------------- /lib/editor/components/Attributes/README.md: -------------------------------------------------------------------------------- 1 | # 属性编辑器界面 2 | -------------------------------------------------------------------------------- /lib/editor/components/Attributes/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | } 3 | 4 | .lockInfo { 5 | display: flex; 6 | flex-direction: column; 7 | padding: var(--vd-spacing-sm); 8 | margin: var(--vd-spacing-xs); 9 | background-color: var(--vd-color-warning-100); 10 | color: var(--vd-color-warning-900); 11 | border-radius: 4px; 12 | align-items: center; 13 | font-weight: bold; 14 | 15 | :global(.ant-btn) { 16 | margin-top: var(--vd-spacing-xs); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/editor/components/Configuration/index.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | import { BaseNode } from '../../Model'; 3 | 4 | export interface EditorConfigurationValue { 5 | /** 6 | * 标题渲染 7 | * @param node 8 | * @returns 9 | */ 10 | renderTitle?: (node: BaseNode) => React.ReactNode; 11 | } 12 | 13 | const CONTEXT = createContext({}); 14 | CONTEXT.displayName = 'EditorConfiguration'; 15 | 16 | export function useEditorConfiguration() { 17 | return useContext(CONTEXT); 18 | } 19 | 20 | export const EditorConfigurationProvider = CONTEXT.Provider; 21 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormCollapse.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.ant-collapse-item:not(:last-child)) { 3 | border-bottom: 1px solid var(--vd-color-border-light); 4 | } 5 | 6 | :global(.ant-collapse-header) { 7 | padding: var(--vd-spacing-xs) !important; 8 | user-select: none; 9 | font-size: var(--vd-font-size-h6); 10 | line-height: var(--vd-font-line-height-h6) !important; 11 | align-items: center !important; 12 | background-color: var(--vd-color-gray-100); 13 | font-weight: bold; 14 | } 15 | 16 | :global(.ant-collapse-content-box) { 17 | padding: var(--vd-spacing-xs) !important; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormContainer.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 100%; 3 | padding: var(--vd-spacing-xs); 4 | } 5 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormContainer.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | import { memo } from 'react'; 3 | 4 | import s from './FormContainer.module.scss'; 5 | 6 | export interface EditorFormContainerProps { 7 | style?: React.CSSProperties; 8 | className?: string; 9 | children?: React.ReactNode; 10 | } 11 | 12 | export const EditorFormContainer = memo((props: EditorFormContainerProps) => { 13 | const { className, ...other } = props; 14 | return
; 15 | }); 16 | 17 | EditorFormContainer.displayName = 'EditorFormContainer'; 18 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | import { FormModel } from '../../Model'; 3 | 4 | export interface EditorFormContext { 5 | /** 6 | * 表单模型 7 | */ 8 | formModel: FormModel; 9 | 10 | /** 11 | * 只读状态 12 | */ 13 | readonly: boolean; 14 | } 15 | 16 | const Context = createContext(null); 17 | Context.displayName = 'EditorFormContext'; 18 | 19 | export function useEditorFormContext() { 20 | return useContext(Context); 21 | } 22 | 23 | export const EditorFormContextProvider = Context.Provider; 24 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormIssues.module.scss: -------------------------------------------------------------------------------- 1 | .list { 2 | list-style: none; 3 | padding: 0; 4 | white-space: pre-wrap; 5 | 6 | color: var(--vd-color-font-regular); 7 | font-size: var(--vd-font-size-h6); 8 | 9 | :global(.anticon) { 10 | margin-right: 4px; 11 | vertical-align: middle; 12 | } 13 | } 14 | 15 | .group { 16 | list-style: none; 17 | padding: 0; 18 | font-size: var(--vd-font-size-h5); 19 | } 20 | 21 | .groupItem { 22 | margin-bottom: var(--vd-spacing-sm); 23 | } 24 | 25 | .groupBody { 26 | padding-left: var(--vd-spacing-xs); 27 | } 28 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormItem.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 100%; 3 | height: 100%; 4 | margin-bottom: var(--vd-spacing-sm); 5 | 6 | :global(.vd-form-tooltip) { 7 | margin-left: 4px; 8 | } 9 | } 10 | 11 | .label { 12 | display: flex; 13 | align-items: center; 14 | justify-content: flex-start; 15 | padding-bottom: 4px; 16 | font-size: var(--vd-font-size-h6); 17 | color: var(--vd-color-font-regular); 18 | } 19 | 20 | .body { 21 | width: 100%; 22 | } 23 | 24 | .required { 25 | color: var(--vd-color-danger); 26 | } 27 | -------------------------------------------------------------------------------- /lib/editor/components/Form/FormRevalidateSpin.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | margin-left: var(--vd-spacing-xs); 3 | color: var(--vd-color-gray-600); 4 | cursor: pointer; 5 | } 6 | -------------------------------------------------------------------------------- /lib/editor/components/Form/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Form'; 2 | export * from './FormItem'; 3 | export * from './FormConsumer'; 4 | export * from './FormContainer'; 5 | export * from './FormCollapse'; 6 | export { useEditorFormContext } from './FormContext'; 7 | export * from './FormPortal'; 8 | export * from './FormTooltip'; 9 | -------------------------------------------------------------------------------- /lib/editor/components/InspectPanel/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 100%; 3 | height: 100%; 4 | :global(.ant-tabs-nav) { 5 | height: 37px; 6 | margin-bottom: 0 !important; 7 | } 8 | 9 | :global(.ant-tabs-content) { 10 | height: 100%; 11 | } 12 | 13 | :global(.ant-tabs-tabpane) { 14 | height: 100%; 15 | overflow: auto; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/editor/components/NodeVisibleControl/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | color: var(--vd-color-gray-500); 3 | margin-left: var(--vd-spacing-xs); 4 | cursor: pointer; 5 | 6 | &:global(.visible) { 7 | color: var(--vd-color-gray-700); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/editor/components/Problems/README.md: -------------------------------------------------------------------------------- 1 | # 告警界面 2 | -------------------------------------------------------------------------------- /lib/editor/components/Problems/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: var(--vd-spacing-xs); 3 | } 4 | 5 | .list { 6 | list-style: none; 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | .itemName { 12 | color: var(--vd-color-font-regular); 13 | font-size: var(--vd-font-size-h5); 14 | cursor: pointer; 15 | &:hover { 16 | text-decoration: underline; 17 | } 18 | } 19 | 20 | .itemBody { 21 | margin-left: var(--vd-spacing-xs); 22 | } 23 | -------------------------------------------------------------------------------- /lib/editor/components/SelectNodePlease/index.tsx: -------------------------------------------------------------------------------- 1 | import { Empty } from 'antd'; 2 | import { memo } from 'react'; 3 | 4 | export const SelectNodePlease = memo((props: { description?: React.ReactNode }) => { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | }); 11 | 12 | SelectNodePlease.displayName = 'SelectNodePlease'; 13 | -------------------------------------------------------------------------------- /lib/editor/components/ShapeLibrary/ShapeItem/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: center; 5 | width: 60px; 6 | padding-bottom: var(--vd-spacing-sm); 7 | cursor: pointer; 8 | } 9 | 10 | .icon { 11 | width: 40px; 12 | height: 40px; 13 | 14 | img { 15 | width: 100%; 16 | height: 100%; 17 | object-fit: contain; 18 | } 19 | } 20 | 21 | .name { 22 | margin-top: var(--vd-spacing-xs); 23 | color: var(--vd-color-font-regular); 24 | font-size: var(--vd-font-size-h6); 25 | } 26 | -------------------------------------------------------------------------------- /lib/editor/components/ShapeLibrary/index.module.scss: -------------------------------------------------------------------------------- 1 | .list { 2 | padding: var(--vd-spacing-sm) var(--vd-spacing-xs); 3 | display: flex; 4 | flex-wrap: wrap; 5 | gap: var(--vd-spacing-xs); 6 | } 7 | -------------------------------------------------------------------------------- /lib/editor/components/Toolbar/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | height: 37px !important; 3 | border-bottom: 1px solid var(--vd-color-border-light); 4 | position: relative; 5 | background-color: white; 6 | z-index: 2; 7 | } 8 | -------------------------------------------------------------------------------- /lib/editor/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Layout'; 2 | export * from './Panel'; 3 | export * from './ShapeLibrary'; 4 | export * from './Toolbar'; 5 | export * from './Form'; 6 | export * from './InspectPanel'; 7 | export * from './NodeVisibleControl'; 8 | export * from './Configuration'; 9 | -------------------------------------------------------------------------------- /lib/editor/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './usePropertyLocationNavigate'; 2 | export * from './usePropertyLocationSatisfy'; 3 | export * from './useCanvasModelCommandDescription'; 4 | -------------------------------------------------------------------------------- /lib/editor/hooks/useCanvasModelCommandDescription.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react'; 2 | import { useCanvasModel } from '../Canvas'; 3 | import memoize from 'lodash/memoize'; 4 | 5 | export function useCanvasModelCommandDescription() { 6 | const { model } = useCanvasModel(); 7 | 8 | const getDesc = useMemo(() => { 9 | return memoize((name: string) => { 10 | const desc = model.getCommandDescription(name); 11 | 12 | return { tooltip: `${desc.description ?? desc.title} (${desc.key.toUpperCase()})`, handler: desc.handler }; 13 | }); 14 | }, [model]); 15 | 16 | return getDesc; 17 | } 18 | -------------------------------------------------------------------------------- /lib/editor/hooks/usePropertyLocationNavigate.ts: -------------------------------------------------------------------------------- 1 | import { useEditorModel, EditorPropertyLocation } from '../Model'; 2 | 3 | /** 4 | * 属性定位/跳转 5 | */ 6 | export function usePropertyLocationNavigate() { 7 | const { model } = useEditorModel(); 8 | 9 | return function open(params: EditorPropertyLocation) { 10 | return model.propertyLocationObserver.emit(params); 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /lib/editor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Model'; 2 | export * from './Shape'; 3 | export * from './Canvas'; 4 | 5 | export * from './hooks'; 6 | export * from './components'; 7 | -------------------------------------------------------------------------------- /lib/framework/base/BaseModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 模型基类 3 | */ 4 | import { EventArgument, EventBus, EventName, inject, injectable } from '@wakeapp/framework-core'; 5 | 6 | @injectable() 7 | export class BaseModel { 8 | @inject('DI.global.eventBus') 9 | protected eventBus!: EventBus; 10 | 11 | protected emit>(name: N, args: A): void { 12 | this.eventBus.emit(name, args); 13 | } 14 | 15 | protected emitError(error: Error) { 16 | this.eventBus.emit('Event.global.error', error); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/framework/base/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BaseModel'; 2 | -------------------------------------------------------------------------------- /lib/framework/components/DIContainerContext.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, container } from '@wakeapp/framework-core'; 3 | 4 | export const DIContainerContext = React.createContext(container); 5 | -------------------------------------------------------------------------------- /lib/framework/components/DIContainerProvider.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import { Container } from '@wakeapp/framework-core'; 3 | 4 | import { DIContainerContext } from './DIContainerContext'; 5 | 6 | /** 7 | * 提供依赖注入容器. 下级组件将优先从这个容器获取依赖 8 | * @param props 9 | * @returns 10 | */ 11 | export const DIContainerProvider: FC<{ container: Container; children?: React.ReactNode }> = props => { 12 | return {props.children}; 13 | }; 14 | -------------------------------------------------------------------------------- /lib/framework/components/README.md: -------------------------------------------------------------------------------- 1 | # React 组件 2 | -------------------------------------------------------------------------------- /lib/framework/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DIContainerProvider'; 2 | -------------------------------------------------------------------------------- /lib/framework/di/index.ts: -------------------------------------------------------------------------------- 1 | export * from './methods'; 2 | -------------------------------------------------------------------------------- /lib/framework/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useDIContainer'; 2 | export * from './useInject'; 3 | export * from './useInjectAll'; 4 | export * from './useMultiInject'; 5 | export * from './useInjectComponent'; 6 | export * from './useEventBus'; 7 | export * from './useEventBusListener'; 8 | -------------------------------------------------------------------------------- /lib/framework/hooks/useDIContainer.test.ts: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react'; 2 | import { container } from '@wakeapp/framework-core'; 3 | 4 | import { useDIContainer } from './useDIContainer'; 5 | 6 | test('默认获取到全局 container', () => { 7 | const { result } = renderHook(() => useDIContainer()); 8 | 9 | expect(result.current).toBe(container); 10 | }); 11 | -------------------------------------------------------------------------------- /lib/framework/hooks/useDIContainer.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { Container } from '@wakeapp/framework-core'; 3 | import { DIContainerContext } from '../components/DIContainerContext'; 4 | 5 | /** 6 | * 获取依赖注入容器 7 | * @returns 8 | */ 9 | export function useDIContainer(): Container { 10 | return useContext(DIContainerContext); 11 | } 12 | -------------------------------------------------------------------------------- /lib/framework/hooks/useEventBus.test.ts: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react'; 2 | import { eventBus } from '@wakeapp/framework-core'; 3 | 4 | import { useEventBus } from './useEventBus'; 5 | 6 | test('默认获取到全局 eventBus', () => { 7 | const { result } = renderHook(() => useEventBus()); 8 | 9 | expect(result.current).toBe(eventBus); 10 | }); 11 | -------------------------------------------------------------------------------- /lib/framework/hooks/useEventBus.ts: -------------------------------------------------------------------------------- 1 | import { EventBus } from '@wakeapp/framework-core'; 2 | import { useInject } from './useInject'; 3 | 4 | /** 5 | * 获取事件总线 6 | * @returns 7 | */ 8 | export function useEventBus(): EventBus { 9 | return useInject('DI.global.eventBus'); 10 | } 11 | -------------------------------------------------------------------------------- /lib/framework/hooks/useMultiInject.ts: -------------------------------------------------------------------------------- 1 | import { useInjectAll } from './useInjectAll'; 2 | 3 | /** 4 | * useInject All 的别名 5 | */ 6 | export const useMultiInject = useInjectAll; 7 | -------------------------------------------------------------------------------- /lib/framework/index.ts: -------------------------------------------------------------------------------- 1 | import './polyfill'; 2 | import './initialize'; 3 | 4 | export * from '@wakeapp/framework-core'; 5 | export * from './di'; 6 | export * from './base'; 7 | export * from './components'; 8 | export * from './hooks'; 9 | export { createPageScope } from './initialize'; 10 | -------------------------------------------------------------------------------- /lib/framework/initialize.ts: -------------------------------------------------------------------------------- 1 | import { setCurrentPageInstanceGetter, clearPageScope } from '@wakeapp/framework-core'; 2 | 3 | let currentPageScope: any; 4 | 5 | export function createPageScope() { 6 | const instance = (currentPageScope = {}); 7 | 8 | return () => { 9 | clearPageScope(instance); 10 | }; 11 | } 12 | 13 | setCurrentPageInstanceGetter(() => { 14 | if (currentPageScope == null) { 15 | throw new Error(`页面作用域的依赖注入只能用于组件内部`); 16 | } 17 | 18 | return currentPageScope; 19 | }); 20 | -------------------------------------------------------------------------------- /lib/framework/polyfill.ts: -------------------------------------------------------------------------------- 1 | // 不再需要,taro 内部已经不再依赖 inversify 2 | // import '@tarojs/runtime'; 3 | import 'reflect-metadata'; 4 | -------------------------------------------------------------------------------- /lib/g6-binding/CellBinding/context.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | import { CellContextValue } from './types'; 3 | 4 | const Context = createContext(null); 5 | 6 | export function useCellContext() { 7 | return useContext(Context); 8 | } 9 | 10 | export const CellContextProvider = Context.Provider; 11 | -------------------------------------------------------------------------------- /lib/g6-binding/EdgeBinding/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | import { EdgeBindingProps } from './types'; 3 | import { useEdge } from './useEdge'; 4 | 5 | export * from './types'; 6 | 7 | export const EdgeBinding = memo((props: EdgeBindingProps) => { 8 | useEdge({ props }); 9 | 10 | return null; 11 | }); 12 | 13 | EdgeBinding.displayName = 'EdgeBinding'; 14 | -------------------------------------------------------------------------------- /lib/g6-binding/NodeBinding/index.tsx: -------------------------------------------------------------------------------- 1 | import { CellContextProvider } from '../CellBinding/context'; 2 | import { NodeBindingProps } from './types'; 3 | import { useNode } from './useNode'; 4 | 5 | export * from './types'; 6 | 7 | export const NodeBinding = (props: NodeBindingProps) => { 8 | const { canBeParent = true } = props; 9 | const { contextValue } = useNode({ props, canBeParent }); 10 | 11 | if (canBeParent) { 12 | return {props.children}; 13 | } else { 14 | return null; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /lib/g6-binding/NodeShapeBinding/RectBinding.tsx: -------------------------------------------------------------------------------- 1 | import { Shape } from '@antv/x6'; 2 | 3 | import { NodeBindingProps } from '../NodeBinding'; 4 | 5 | import { createShape } from './createShape'; 6 | 7 | export const RectBinding = createShape( 8 | Shape.Rect, 9 | [{ name: 'label', getter: 'getLabel', setter: 'setLabel', remover: 'removeLabel' }], 10 | 'RectBinding' 11 | ); 12 | -------------------------------------------------------------------------------- /lib/g6-binding/NodeShapeBinding/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './RectBinding'; 2 | export * from './ReactComponentBinding'; 3 | -------------------------------------------------------------------------------- /lib/g6-binding/README.md: -------------------------------------------------------------------------------- 1 | # 封装 G6 组件,将命令式的 G6 转换为响应式 2 | -------------------------------------------------------------------------------- /lib/g6-binding/ReactTools/BBox.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: absolute; 3 | width: 0; 4 | height: 0; 5 | left: 0; 6 | top: 0; 7 | pointer-events: none; 8 | background-color: transparent; 9 | } 10 | -------------------------------------------------------------------------------- /lib/g6-binding/ReactTools/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BBox'; 2 | -------------------------------------------------------------------------------- /lib/g6-binding/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useEventStore'; 2 | -------------------------------------------------------------------------------- /lib/g6-binding/index.ts: -------------------------------------------------------------------------------- 1 | import './react-shape'; 2 | 3 | export * from './GraphBinding'; 4 | export * from './NodeBinding'; 5 | export * from './CellBinding'; 6 | export * from './NodeShapeBinding'; 7 | export * from './EdgeBinding'; 8 | export * from './ReactTools'; 9 | -------------------------------------------------------------------------------- /lib/g6-binding/react-shape/README.md: -------------------------------------------------------------------------------- 1 | # 支持 React 组件渲染 2 | 3 | fork 自 x6-react-shape 4 | 5 | 修改了 portal 支持多实例并存 6 | -------------------------------------------------------------------------------- /lib/g6-binding/react-shape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './node'; 2 | export * from './view'; 3 | export * from './registry'; 4 | export * from './portal'; 5 | -------------------------------------------------------------------------------- /lib/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useSyncEffect'; 2 | export * from './useIsMacos'; 3 | export * from './useReadableKeyBinding'; 4 | export * from './useTimeout'; 5 | export * from './useLazyFalsy'; 6 | export * from './usePreventUnload'; 7 | export * from './useEventBusListener'; 8 | export * from './useOffline'; 9 | -------------------------------------------------------------------------------- /lib/hooks/useIsMacos.ts: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | const test = (): boolean => { 4 | return /macintosh|mac os x/i.test(window.navigator.userAgent); 5 | }; 6 | 7 | export function useIsMacos() { 8 | const [result] = useState(test); 9 | return result; 10 | } 11 | -------------------------------------------------------------------------------- /lib/hooks/useLazyFalsy.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | export function useLazyFalsy(value: boolean, delay: number = 500) { 4 | const [delayValue, setDelayValue] = useState(value); 5 | 6 | useEffect(() => { 7 | if (value) { 8 | // 如果是正值,则立即更新 9 | setDelayValue(true); 10 | } else { 11 | // 异步更新 12 | const timer = setTimeout(() => { 13 | setDelayValue(false); 14 | }, delay); 15 | 16 | return () => clearTimeout(timer); 17 | } 18 | }, [value, delay]); 19 | 20 | return delayValue; 21 | } 22 | -------------------------------------------------------------------------------- /lib/hooks/useTimeout.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | export function useTimeout() { 4 | const [count, setCount] = useState(0); 5 | 6 | const start = (seconds: number) => { 7 | setCount(seconds); 8 | }; 9 | 10 | useEffect(() => { 11 | if (count > 0) { 12 | const timer = setTimeout(() => { 13 | setCount(count - 1); 14 | }, 1000); 15 | 16 | return () => clearTimeout(timer); 17 | } 18 | }, [count]); 19 | 20 | return { count, start }; 21 | } 22 | -------------------------------------------------------------------------------- /lib/openai-event-source/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * openAI EventSource 数据消费 3 | */ 4 | export * from './OpenAIEventSourceModel'; 5 | export * from './useOpenAI'; 6 | export * from './decode'; 7 | export * from './Loading'; 8 | export * from './PromptModal'; 9 | export * from './LoadingIcon'; 10 | export { isAbort } from './stream'; 11 | -------------------------------------------------------------------------------- /lib/openai-event-source/useOpenAI.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useMemo } from 'react'; 2 | import { tryDispose } from '@/lib/utils'; 3 | 4 | import { OpenAIEventSourceModel, OpenAIEventSourceModelOptions } from './OpenAIEventSourceModel'; 5 | 6 | export function useOpenAI(options: OpenAIEventSourceModelOptions, deps: any[] = []) { 7 | const model = useMemo(() => new OpenAIEventSourceModel(options), deps); 8 | 9 | useEffect(() => { 10 | return () => { 11 | tryDispose(model); 12 | }; 13 | }, [model]); 14 | 15 | return model; 16 | } 17 | -------------------------------------------------------------------------------- /lib/polyfill/index.ts: -------------------------------------------------------------------------------- 1 | // 一些自定义 polyfill 2 | // nextjs 内置的polyfill 见 https://github.com/vercel/next.js/tree/canary/packages/next-polyfill-nomodule/src 3 | // 在 _app 顶部导入 4 | import 'core-js/features/global-this'; 5 | import 'core-js/features/array/at'; 6 | -------------------------------------------------------------------------------- /lib/store/README.md: -------------------------------------------------------------------------------- 1 | # MODEL 层相关工具封装 2 | -------------------------------------------------------------------------------- /lib/store/derive.test.ts: -------------------------------------------------------------------------------- 1 | import { autorun, observable } from 'mobx'; 2 | import { derive } from './derive'; 3 | 4 | test('derive', () => { 5 | const a = observable({ count: 1 }); 6 | const fn = jest.fn(() => a.count + 1); 7 | const c = derive(fn); 8 | 9 | expect(c.get()).toBe(2); 10 | expect(fn).toBeCalledTimes(1); 11 | 12 | autorun(() => { 13 | c.get(); 14 | }); 15 | 16 | expect(c.get()).toBe(2); 17 | expect(fn).toBeCalledTimes(2); 18 | 19 | // 如果有跟踪者,计算会缓存 20 | expect(c.get()).toBe(2); 21 | expect(fn).toBeCalledTimes(2); 22 | }); 23 | -------------------------------------------------------------------------------- /lib/store/derive.ts: -------------------------------------------------------------------------------- 1 | import { computed } from 'mobx'; 2 | 3 | export const derive = computed; 4 | -------------------------------------------------------------------------------- /lib/store/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mutation'; 2 | export * from './derive'; 3 | export * from './effect'; 4 | export * from './command'; 5 | export * from './push'; 6 | export * from './pull'; 7 | export { makeAutoBindThis } from './auto-bind-this'; 8 | -------------------------------------------------------------------------------- /lib/typescript/README.md: -------------------------------------------------------------------------------- 1 | # Typescript 类型生成 2 | -------------------------------------------------------------------------------- /lib/typescript/comment.ts: -------------------------------------------------------------------------------- 1 | export function generateComment(lines: (string | undefined)[], style: 'block' | 'inline') { 2 | const comments = lines.filter(i => i != null && i !== ''); 3 | 4 | if (!comments.length) { 5 | return ''; 6 | } 7 | 8 | const codeLines: string[] = []; 9 | 10 | if (style === 'block') { 11 | codeLines.push('/**'); 12 | comments.forEach(i => codeLines.push(` * ${i}`)); 13 | codeLines.push(' */'); 14 | } else { 15 | comments.forEach(i => codeLines.push(`// ${i}`)); 16 | } 17 | 18 | return codeLines.join('\n'); 19 | } 20 | -------------------------------------------------------------------------------- /lib/typescript/index.ts: -------------------------------------------------------------------------------- 1 | export * from './comment'; 2 | export * from './interface'; 3 | export * from './enum'; 4 | -------------------------------------------------------------------------------- /lib/typescript/types.ts: -------------------------------------------------------------------------------- 1 | export interface Comment { 2 | /** 3 | * 标题 4 | */ 5 | title?: string; 6 | 7 | /** 8 | * 消息描述 9 | */ 10 | description?: string; 11 | } 12 | -------------------------------------------------------------------------------- /lib/typescript/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 将指定代码进行缩进 3 | * @param code 4 | * @param count 5 | */ 6 | export function indent(code: string, count: number = 1) { 7 | if (!code) { 8 | return code; 9 | } 10 | 11 | const lines = code.split('\n'); 12 | const spaces = ' '.repeat(count); 13 | const result = lines.map(i => `${spaces}${i}`); 14 | return result.join('\n'); 15 | } 16 | -------------------------------------------------------------------------------- /lib/utils/Clipboard.ts: -------------------------------------------------------------------------------- 1 | import { action, computed, makeObservable, observable } from 'mobx'; 2 | 3 | export class Clipboard { 4 | @observable.shallow 5 | private items: T[] = []; 6 | 7 | constructor() { 8 | makeObservable(this); 9 | } 10 | 11 | @computed 12 | get isEmpty() { 13 | return !this.items?.length; 14 | } 15 | 16 | @action 17 | save(items: T[]) { 18 | this.items = items; 19 | } 20 | 21 | get() { 22 | return this.items; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/utils/EventBus.test.ts: -------------------------------------------------------------------------------- 1 | import { EventBus } from './EventBus'; 2 | 3 | test('not ready', () => { 4 | const bus = new EventBus<{ test: never }>({ notReadyYet: true }); 5 | const fn = jest.fn(); 6 | 7 | bus.on('test', fn); 8 | bus.emit('test'); 9 | 10 | expect(fn).not.toBeCalled(); 11 | bus.iAmReady(); 12 | expect(fn).toBeCalledTimes(1); 13 | }); 14 | -------------------------------------------------------------------------------- /lib/utils/IDestroyable.ts: -------------------------------------------------------------------------------- 1 | export interface IDestroyable { 2 | destroy(): void; 3 | } 4 | -------------------------------------------------------------------------------- /lib/utils/IDisposable.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from '@wakeapp/utils'; 2 | 3 | export interface IDisposable { 4 | /** 5 | * 析构器 6 | * @returns 7 | */ 8 | dispose?: () => void; 9 | } 10 | 11 | /** 12 | * 尝试释放 13 | * @param maybeDisposable 14 | */ 15 | export function tryDispose(maybeDisposable: any) { 16 | if (isObject(maybeDisposable) && 'dispose' in maybeDisposable && typeof maybeDisposable.dispose === 'function') { 17 | maybeDisposable.dispose(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/utils/ISerializable.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 可序列化接口 3 | */ 4 | export interface ISerializable { 5 | fromJSON(data: D): void; 6 | toJSON(): D; 7 | } 8 | -------------------------------------------------------------------------------- /lib/utils/abort.ts: -------------------------------------------------------------------------------- 1 | export function isAbort(err: any) { 2 | if (err instanceof DOMException && err.name === 'AbortError') { 3 | return true; 4 | } 5 | return false; 6 | } 7 | -------------------------------------------------------------------------------- /lib/utils/array.test.ts: -------------------------------------------------------------------------------- 1 | import { toArray, randomPick } from './array'; 2 | 3 | test('toArray', () => { 4 | expect(toArray(1)).toEqual([1]); 5 | expect(toArray([1])).toEqual([1]); 6 | expect(toArray(undefined)).toEqual([]); 7 | }); 8 | 9 | test('randomPick', () => { 10 | expect(randomPick([1])).toEqual(1); 11 | expect(randomPick([])).toEqual(undefined); 12 | expect([1, 2, 3].includes(randomPick([1, 2, 3]))).toBeTruthy(); 13 | }); 14 | -------------------------------------------------------------------------------- /lib/utils/array.ts: -------------------------------------------------------------------------------- 1 | import { NoopArray } from '@wakeapp/utils'; 2 | 3 | export function toArray(maybeArray: T | T[] | undefined): T[] { 4 | return Array.isArray(maybeArray) ? maybeArray : maybeArray ? [maybeArray] : NoopArray; 5 | } 6 | 7 | /** 8 | * 从数组中随机取出一个元素 9 | */ 10 | export function randomPick(array: T[]): T { 11 | return array[Math.floor(Math.random() * array.length)]; 12 | } 13 | -------------------------------------------------------------------------------- /lib/utils/assert.test.ts: -------------------------------------------------------------------------------- 1 | // test assert 2 | import { assert } from './assert'; 3 | 4 | describe('assert', () => { 5 | it('should throw error', () => { 6 | expect(() => { 7 | assert(false, 'error'); 8 | }).toThrowError('error'); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /lib/utils/assert.ts: -------------------------------------------------------------------------------- 1 | export function assert(condition: any, message?: string): asserts condition { 2 | if (!condition) { 3 | throw new Error(message); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/utils/color.test.ts: -------------------------------------------------------------------------------- 1 | import { getMappedColor, getMappedLighterColor } from './color'; 2 | 3 | test('test getMappedColor', () => { 4 | expect(getMappedColor('test')).toBe('#b36d3d'); 5 | expect(getMappedColor('test')).toBe('#b36d3d'); 6 | expect(getMappedColor('hello world')).toBe('#70b351'); 7 | }); 8 | 9 | test('test getMappedLighterColor', () => { 10 | expect(getMappedLighterColor('test')).toBe('#7FFFD4'); 11 | expect(getMappedLighterColor('test')).toBe('#7FFFD4'); 12 | 13 | expect(getMappedLighterColor('hello world')).toBe('#FFC0CB'); 14 | }); 15 | -------------------------------------------------------------------------------- /lib/utils/filter.ts: -------------------------------------------------------------------------------- 1 | export function ignoreFalse(value: T | false): value is T { 2 | return Boolean(value); 3 | } 4 | 5 | export function elseUndefined(value: any): true | undefined { 6 | if (value) { 7 | return true; 8 | } 9 | return undefined; 10 | } 11 | -------------------------------------------------------------------------------- /lib/utils/hash.ts: -------------------------------------------------------------------------------- 1 | export function toHex(data: Uint8Array) { 2 | return Array.from(data) 3 | .map(byte => byte.toString(16).padStart(2, '0')) 4 | .join(''); 5 | } 6 | 7 | /** 8 | * Create a SHA-256 hash of the given data. 9 | * @param data 10 | * @returns 11 | */ 12 | export async function createShaHash(data: Uint8Array) { 13 | const digest = await crypto.subtle.digest('SHA-256', data); 14 | return toHex(new Uint8Array(digest)); 15 | } 16 | -------------------------------------------------------------------------------- /lib/utils/name-case.test.ts: -------------------------------------------------------------------------------- 1 | import { normalizedCamelCase } from './name-case'; 2 | 3 | test('expect', () => { 4 | expect(normalizedCamelCase('a')).toBe('a'); 5 | expect(normalizedCamelCase('A')).toBe('a'); 6 | expect(normalizedCamelCase('ABC')).toBe('abc'); 7 | expect(normalizedCamelCase('ABCDom')).toBe('abcDom'); 8 | expect(normalizedCamelCase('ABC', true)).toBe('ABC'); 9 | expect(normalizedCamelCase('abcABC')).toBe('abcABC'); 10 | }); 11 | -------------------------------------------------------------------------------- /lib/utils/object.test.ts: -------------------------------------------------------------------------------- 1 | import { getPrefixPath, getParentPath } from './object'; 2 | 3 | test('getPrefixPath', () => { 4 | expect(getPrefixPath('a.b.c', 'b')).toBe('a.b'); 5 | expect(getPrefixPath('a.b.c', 'c')).toBe('a.b.c'); 6 | expect(getPrefixPath('a.b.c', 'd')).toBe('a.b.c'); 7 | expect(getPrefixPath('arr.0.center.c', 'center')).toBe('arr.0.center'); 8 | }); 9 | 10 | test('getParentPath', () => { 11 | expect(getParentPath('a.b.c')).toBe('a.b'); 12 | expect(getParentPath('a[0]')).toBe('a'); 13 | expect(getParentPath('a[0].c')).toBe('a.0'); 14 | expect(getParentPath('a')).toBe(''); 15 | }); 16 | -------------------------------------------------------------------------------- /lib/utils/price.ts: -------------------------------------------------------------------------------- 1 | export function toYuan(num: number, precision: number = 2): string { 2 | return (num / 100).toFixed(precision); 3 | } 4 | 5 | export function YuanToFen(num: number): number { 6 | return (num * 100) | 0; 7 | } 8 | -------------------------------------------------------------------------------- /lib/utils/promise.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取 Promise 的异常值,如果没有抛出异常,则返回 null 3 | * @param promise 4 | */ 5 | export function catchPromise(promise: Promise): Promise { 6 | return new Promise(resolve => { 7 | promise 8 | .then(() => { 9 | resolve(null); 10 | }) 11 | .catch(err => { 12 | resolve(err); 13 | }); 14 | }); 15 | } 16 | 17 | /** 18 | * never fulfilled 19 | * @returns 20 | */ 21 | export function forever() { 22 | return new Promise(() => {}); 23 | } 24 | -------------------------------------------------------------------------------- /lib/utils/url.ts: -------------------------------------------------------------------------------- 1 | const DEFAULT_ORIGIN = 'https://ddd.wakedt.cn'; 2 | 3 | export function normalizeUrl(url: string) { 4 | try { 5 | const parsed = new URL(url, DEFAULT_ORIGIN); 6 | return `${parsed.pathname}${parsed.search}${parsed.hash}`; 7 | } catch (err) { 8 | return null; 9 | } 10 | } 11 | 12 | export function toUrl(url: string) { 13 | try { 14 | return new URL(url, DEFAULT_ORIGIN); 15 | } catch { 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/CodeBlockComponent.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: relative; 3 | } 4 | 5 | .select { 6 | position: absolute; 7 | right: 8px; 8 | top: 6px; 9 | border: none; 10 | background-color: transparent; 11 | color: var(--vd-color-gray-500); 12 | outline: none; 13 | text-align: right; 14 | padding: 0 4px; 15 | font-size: 14px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/CustomBlock/Demo.tsx: -------------------------------------------------------------------------------- 1 | import { registerBlock } from '../ReactBlock'; 2 | 3 | registerBlock<{ count: number }>({ 4 | name: 'demo', 5 | title: 'Demo', 6 | initialState: () => ({ count: 0 }), 7 | render({ state, updateState }) { 8 | return ( 9 |
{ 11 | updateState({ count: state.count + 1 }); 12 | }} 13 | > 14 | hello: {state.count} 15 |
16 | ); 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/CustomBlock/index.ts: -------------------------------------------------------------------------------- 1 | // export * from './Demo' 2 | export * from './CodeSandbox'; 3 | export * from './ProcessOn'; 4 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Document.tsx: -------------------------------------------------------------------------------- 1 | import { Node } from '@tiptap/core'; 2 | 3 | export const Document = Node.create({ 4 | name: 'doc', 5 | 6 | topNode: true, 7 | 8 | // content: "draggableBlock{1,}", // accepts one or more draggable block as content 9 | content: 'dBlock+', 10 | }); 11 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/README.md: -------------------------------------------------------------------------------- 1 | # 富文本编辑器 2 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/ReactBlock/README.md: -------------------------------------------------------------------------------- 1 | # React 自定义渲染块 2 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/ReactBlock/ReactBlockComponent.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/lib/wysiwyg-editor/ReactBlock/ReactBlockComponent.module.scss -------------------------------------------------------------------------------- /lib/wysiwyg-editor/ReactBlock/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Extension'; 2 | export * from './registry'; 3 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Suggestion/README.md: -------------------------------------------------------------------------------- 1 | / 命令展示 2 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Suggestion/icons/index.ts: -------------------------------------------------------------------------------- 1 | export * from './H1'; 2 | export * from './H2'; 3 | export * from './H3'; 4 | export * from './H4'; 5 | export * from './Bold'; 6 | export * from './Default'; 7 | export * from './Paragraph'; 8 | export * from './Code'; 9 | export * from './List'; 10 | export * from './ListOrder'; 11 | export * from './Quote'; 12 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Suggestion/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Commands'; 2 | export * from './items'; 3 | export * from './renderItem'; 4 | export { isActive } from './suggestion'; 5 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Suggestion/suggestion/index.ts: -------------------------------------------------------------------------------- 1 | import { Suggestion } from './suggestion'; 2 | 3 | export * from './findSuggestionMatch'; 4 | export * from './suggestion'; 5 | 6 | export default Suggestion; 7 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Suggestion/types.ts: -------------------------------------------------------------------------------- 1 | import type { Editor, Range } from '@tiptap/core'; 2 | 3 | export interface Props {} 4 | 5 | export interface Item { 6 | /** 7 | * 英文名称 8 | */ 9 | name: string; 10 | 11 | /** 12 | * 可读标题 13 | */ 14 | title: string; 15 | 16 | icon?: React.ComponentType; 17 | 18 | /** 19 | * 执行命令 20 | * @param props 21 | * @returns 22 | */ 23 | command: (props: CommandParams) => void; 24 | 25 | /** 26 | * 分类 27 | */ 28 | category: string; 29 | } 30 | 31 | interface CommandParams extends Props { 32 | editor: Editor; 33 | range: Range; 34 | } 35 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Toolbar/ImageEditor.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | min-width: 250px; 3 | outline: none; 4 | :global { 5 | .ant-tabs-nav { 6 | margin-bottom: 8px; 7 | } 8 | 9 | .ant-tabs-tab { 10 | padding: 4px 0 !important; 11 | } 12 | } 13 | } 14 | 15 | .upload { 16 | display: flex; 17 | align-items: center; 18 | justify-content: center; 19 | min-height: 80px; 20 | } 21 | 22 | .external { 23 | display: flex; 24 | flex-direction: column; 25 | justify-content: center; 26 | gap: 8px; 27 | min-height: 80px; 28 | } 29 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Toolbar/JustifyIcon.tsx: -------------------------------------------------------------------------------- 1 | export const JustifyIcon = () => { 2 | return ( 3 | 11 | 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Toolbar/LinkEditor.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | flex-direction: column; 4 | gap: 8px; 5 | align-items: flex-end; 6 | } 7 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/Toolbar/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/lib/wysiwyg-editor/Toolbar/index.module.scss -------------------------------------------------------------------------------- /lib/wysiwyg-editor/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 最大图片大小 3 | */ 4 | export const MAX_IMAGE_SIZE = 1024 * 1024 * 5; 5 | -------------------------------------------------------------------------------- /lib/wysiwyg-editor/utils.ts: -------------------------------------------------------------------------------- 1 | import { MAX_IMAGE_SIZE } from './constants'; 2 | 3 | export function isValidImage(file: File) { 4 | return file.type.startsWith('image/') && file.size <= MAX_IMAGE_SIZE; 5 | } 6 | 7 | export function transformFileToBase64(file: File) { 8 | return new Promise((resolve, reject) => { 9 | const reader = new FileReader(); 10 | reader.onload = () => { 11 | resolve(reader.result as string); 12 | }; 13 | reader.onerror = reject; 14 | reader.readAsDataURL(file); 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /lib/yjs-reverse/README.md: -------------------------------------------------------------------------------- 1 | # 支持 yjs 回滚 2 | 3 | https://discuss.yjs.dev/t/is-there-a-way-to-revert-to-specific-version/379/6 4 | -------------------------------------------------------------------------------- /lib/yjs-store-api-for-browser/raw.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 存储在数据库的原始 Yjs 数据 3 | */ 4 | import { toUint8Array } from 'js-base64'; 5 | export type RawYjsData = string; 6 | 7 | type Base64 = string; 8 | 9 | interface RawPayload { 10 | version: '1.0'; 11 | data: Base64; 12 | timestamp: number; 13 | } 14 | 15 | export function readRawData(raw: RawYjsData): Uint8Array { 16 | if (raw.startsWith('{') && raw.endsWith('}')) { 17 | // JSON 数据 18 | const payload: RawPayload = JSON.parse(raw); 19 | 20 | return toUint8Array(payload.data); 21 | } else { 22 | // 初版的 base64 数据 23 | return toUint8Array(raw); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/yjs-store-api/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { readBufferFromReadableStream } from './utils'; 2 | import { PassThrough } from 'stream'; 3 | 4 | test('readBufferFromReadableStream', async () => { 5 | const readable = new PassThrough(); 6 | const buffer = readBufferFromReadableStream(readable); 7 | 8 | readable.push(Buffer.from('hello')); 9 | readable.push(Buffer.from(' ')); 10 | readable.push(Buffer.from('world')); 11 | readable.end(); 12 | 13 | expect((await buffer).toString()).toBe('hello world'); 14 | }); 15 | -------------------------------------------------------------------------------- /modules/Layout/Content.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | background-color: var(--vd-color-bg); 3 | padding: var(--vd-spacing-sm) var(--vd-spacing-base); 4 | } 5 | -------------------------------------------------------------------------------- /modules/Layout/Content.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | import { observer } from 'mobx-react'; 3 | 4 | import s from './Content.module.scss'; 5 | 6 | export interface ContentProps { 7 | className?: string; 8 | style?: React.CSSProperties; 9 | children: React.ReactNode; 10 | } 11 | 12 | export const Content = observer(function Content(props: ContentProps) { 13 | const { className, children, ...other } = props; 14 | return ( 15 |
16 | {children} 17 |
18 | ); 19 | }); 20 | -------------------------------------------------------------------------------- /modules/Layout/Layout.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: absolute; 3 | left: 0; 4 | top: 0; 5 | width: 100%; 6 | height: 100%; 7 | display: flex; 8 | flex-direction: column; 9 | overflow: hidden; 10 | } 11 | 12 | .header { 13 | height: 45px; 14 | } 15 | 16 | .body { 17 | flex: 1; 18 | display: flex; 19 | overflow: hidden; 20 | } 21 | 22 | .content { 23 | flex: 1; 24 | overflow-x: hidden; 25 | overflow-y: auto; 26 | } 27 | -------------------------------------------------------------------------------- /modules/Layout/User.module.scss: -------------------------------------------------------------------------------- 1 | .avatar { 2 | background-color: var(--vd-color-gray-400); 3 | background-clip: content-box; 4 | cursor: pointer; 5 | } 6 | 7 | .profile { 8 | color: gray; 9 | cursor: default; 10 | } 11 | 12 | .version { 13 | font-size: 12px; 14 | color: var(--vd-color-gray-400); 15 | } 16 | -------------------------------------------------------------------------------- /modules/Layout/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 页面布局 3 | */ 4 | export * from './Layout'; 5 | export { useLayoutTitle } from './Context'; 6 | export * from './types'; 7 | -------------------------------------------------------------------------------- /modules/Layout/utils.ts: -------------------------------------------------------------------------------- 1 | import Router from 'next/router'; 2 | import { LayoutMenu } from './types'; 3 | 4 | export function openMenu(menu: LayoutMenu) { 5 | if (menu.children?.length) { 6 | // 默认打开第一个 7 | Router.push(menu.children[0].route); 8 | } else { 9 | Router.push(menu.route); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /modules/ai/api/chat-supported.ts: -------------------------------------------------------------------------------- 1 | import { allowMethod } from '@/lib/api'; 2 | import { chatSupported } from '../platform'; 3 | import { createSuccessResponse } from '@/modules/backend-node'; 4 | 5 | export const getChatSupported = allowMethod('GET', async (req, res) => { 6 | const supported = chatSupported(); 7 | 8 | res.json(createSuccessResponse(supported)); 9 | }); 10 | -------------------------------------------------------------------------------- /modules/ai/api/models.ts: -------------------------------------------------------------------------------- 1 | import { allowMethod } from '@/lib/api'; 2 | import { getSupportedModels } from '../platform'; 3 | import { createSuccessResponse } from '@/modules/backend-node'; 4 | 5 | /** 6 | * 获取所有支持的模型 7 | */ 8 | export const getModels = allowMethod('GET', async (req, res) => { 9 | // TODO: 根据用户的当前的套件进行筛选 10 | const supported = getSupportedModels(); 11 | 12 | res.json(createSuccessResponse(supported)); 13 | }); 14 | -------------------------------------------------------------------------------- /modules/ai/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api'; 2 | export { chatSupported, getSupportedModels } from './platform'; 3 | -------------------------------------------------------------------------------- /modules/ai/openai.ts: -------------------------------------------------------------------------------- 1 | import { Configuration, OpenAIApi } from 'openai'; 2 | import { getOpenAISupport } from './platform'; 3 | 4 | export function getOpenAIInstance() { 5 | const support = getOpenAISupport(); 6 | 7 | const configuration = new Configuration({ 8 | apiKey: support.key, 9 | basePath: support.basePath, 10 | }); 11 | 12 | const openai = new OpenAIApi(configuration); 13 | 14 | return openai; 15 | } 16 | -------------------------------------------------------------------------------- /modules/ai/rate-limit/IRateLimit.ts: -------------------------------------------------------------------------------- 1 | export interface IRateLimit { 2 | requestUsage(id: string, amount: number): Promise; 3 | 4 | /** 5 | * 获取剩余配额 6 | * @param id 7 | */ 8 | remainUsage(id: string): Promise>; 9 | 10 | /** 11 | * 超出限额提示语 12 | */ 13 | exceedMessage: string; 14 | } 15 | -------------------------------------------------------------------------------- /modules/ai/rate-limit/README.md: -------------------------------------------------------------------------------- 1 | # 模型风控逻辑 2 | -------------------------------------------------------------------------------- /modules/ai/request-control/index.ts: -------------------------------------------------------------------------------- 1 | import { addRequestControlHandler } from './RequestControlChain'; 2 | import { checkPlan } from './planCheck'; 3 | import { checkRateLimit } from './rate-limit-check'; 4 | 5 | addRequestControlHandler(checkPlan); 6 | addRequestControlHandler(checkRateLimit); 7 | 8 | export { checkRequest, RequestControlError, RequestControlErrorCode } from './RequestControlChain'; 9 | -------------------------------------------------------------------------------- /modules/ai/request-control/rate-limit-check.ts: -------------------------------------------------------------------------------- 1 | import { getBasicModelRateLimit } from '../rate-limit'; 2 | 3 | import { RequestControlError, RequestControlErrorCode, RequestControlHandler } from './RequestControlChain'; 4 | 5 | /** 6 | * 模型速率限制 7 | * @param params 8 | */ 9 | export const checkRateLimit: RequestControlHandler = async params => { 10 | const limit = getBasicModelRateLimit(params.model); 11 | 12 | if (!(await limit.requestUsage(params.account, params.amount))) { 13 | throw new RequestControlError(RequestControlErrorCode.RateLimit, limit.exceedMessage ?? '请求过于频繁,请稍后重试'); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /modules/ai/shared.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 客户端和服务端共享的内容 3 | */ 4 | export enum RequestControlErrorCode { 5 | /** 6 | * 不允许使用该功能 7 | */ 8 | FeatureNotAllowed = 405, 9 | 10 | /** 11 | * 超出套餐使用范围,可能需要进行套餐升级 12 | */ 13 | PlanExceed = 426, 14 | 15 | /** 16 | * 速率限制,可能是请求过滤频繁 17 | */ 18 | RateLimit = 429, 19 | } 20 | -------------------------------------------------------------------------------- /modules/ai/usage/README.md: -------------------------------------------------------------------------------- 1 | # 用量统计 2 | 3 | ● 原始消耗 token 数 4 | ● 模型 5 | ● 用户 6 | ● 时期 7 | ● point 8 | -------------------------------------------------------------------------------- /modules/backend-client/README.md: -------------------------------------------------------------------------------- 1 | # 后端接口服务 2 | 3 | 只能在客户端调用 4 | -------------------------------------------------------------------------------- /modules/backend-client/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 是否忽略鉴权错误 3 | */ 4 | export const IGNORE_AUTH_ERROR: unique symbol = Symbol('IGNORE_AUTH_ERROR'); 5 | -------------------------------------------------------------------------------- /modules/backend-client/helper.ts: -------------------------------------------------------------------------------- 1 | import router from 'next/router'; 2 | 3 | export const UNAUTH_CODE = 401; 4 | 5 | export function isUnauth(code: number) { 6 | return code === UNAUTH_CODE; 7 | } 8 | 9 | export function gotoLogin() { 10 | console.debug('跳转到登录页面'); 11 | const url = new URL('/login', globalThis.location.href); 12 | url.searchParams.append('from', router.asPath); 13 | url.searchParams.append('flash', 'true'); 14 | url.searchParams.append('capturer', 'client'); 15 | 16 | router.push(url); 17 | } 18 | -------------------------------------------------------------------------------- /modules/backend-client/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useRequest'; 2 | export * from './useRequestByGet'; 3 | export * from './useRequestByPost'; 4 | export * from './useCacheableRequest'; 5 | export * from './useCleanRequestCache'; 6 | -------------------------------------------------------------------------------- /modules/backend-client/hooks/useCacheableRequest.ts: -------------------------------------------------------------------------------- 1 | import { request } from '../request'; 2 | import { useSWRConfig } from 'swr'; 3 | 4 | // TODO: 实验性 5 | export function useCacheableRequest() { 6 | const { cache } = useSWRConfig(); 7 | 8 | const wrapper: typeof request.request = (key, body, config) => { 9 | const cacheState = cache.get(key); 10 | 11 | if (cacheState?.data && !cacheState.isLoading) { 12 | return cacheState.data; 13 | } 14 | 15 | return request.request(key, body, config); 16 | }; 17 | 18 | return wrapper; 19 | } 20 | -------------------------------------------------------------------------------- /modules/backend-client/hooks/useCleanRequestCache.ts: -------------------------------------------------------------------------------- 1 | import { useSWRConfig } from 'swr'; 2 | 3 | /** 4 | * 清空 swr 缓存 5 | * @returns 6 | */ 7 | export function useCleanRequestCache() { 8 | const { cache } = useSWRConfig(); 9 | 10 | return () => { 11 | for (const k of cache.keys()) { 12 | cache.delete(k); 13 | } 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /modules/backend-client/hooks/useRequestByGet.ts: -------------------------------------------------------------------------------- 1 | import { useRequest, useRequestPagination } from './useRequest'; 2 | 3 | /** 4 | * GET 请求 5 | * @param url 6 | * @param body 7 | * @param config 8 | * @returns 9 | */ 10 | export const useRequestByGet: typeof useRequest = (url, body, config) => { 11 | return useRequest(url, body, { 12 | ...config, 13 | method: 'GET', 14 | }); 15 | }; 16 | 17 | export const useRequestPaginationByGet: typeof useRequestPagination = (url, body, config) => { 18 | return useRequestPagination(url, body, { 19 | ...config, 20 | method: 'GET', 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /modules/backend-client/hooks/useRequestByPost.ts: -------------------------------------------------------------------------------- 1 | import { useRequest, useRequestPagination } from './useRequest'; 2 | 3 | /** 4 | * POST 请求 5 | * @param url 6 | * @param body 7 | * @param config 8 | * @returns 9 | */ 10 | export const useRequestByPost = useRequest; 11 | 12 | export const useRequestPaginationByPost = useRequestPagination; 13 | -------------------------------------------------------------------------------- /modules/backend-client/index.ts: -------------------------------------------------------------------------------- 1 | export * from './request'; 2 | export * from './fetch'; 3 | export * from './helper'; 4 | export * from './hooks'; 5 | export * from './download'; 6 | export * from './constants'; 7 | -------------------------------------------------------------------------------- /modules/backend-node/README.md: -------------------------------------------------------------------------------- 1 | # 后端接口服务 2 | 3 | 只能在 node 端调用 4 | -------------------------------------------------------------------------------- /modules/backend-node/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 后端服务 3 | */ 4 | export const BACKEND = new URL(process.env.BACKEND ?? 'https://ddd.wakedt.cn'); 5 | 6 | /** 7 | * 后端服务前缀 8 | */ 9 | export const API_PREFIX = '/wd'; 10 | -------------------------------------------------------------------------------- /modules/backend-node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './request'; 3 | export * from './parse-set-cookie'; 4 | export * from './serialize-cookie'; 5 | export * from './predicate'; 6 | -------------------------------------------------------------------------------- /modules/backend-node/merge-cookie.test.ts: -------------------------------------------------------------------------------- 1 | import { mergeCookie } from './merge-cookie'; 2 | 3 | test('mergeCookie', () => { 4 | const current = 'a=1; b=2'; 5 | const coming = { c: '3', d: '4', a: '2' }; 6 | const result = mergeCookie(current, coming); 7 | expect(result).toBe('a=2; b=2; c=3; d=4'); 8 | 9 | const result2 = mergeCookie(current, coming, ['a', 'c']); 10 | expect(result2).toBe('b=2; d=4'); 11 | }); 12 | -------------------------------------------------------------------------------- /modules/backend-node/merge-cookie.ts: -------------------------------------------------------------------------------- 1 | import cookie from 'cookie'; 2 | import { serializeCookie } from './serialize-cookie'; 3 | 4 | export function mergeCookie(current: string | undefined | null, coming: Record, toDelete?: string[]) { 5 | let set = current ? cookie.parse(current) : {}; 6 | set = { ...set, ...coming }; 7 | 8 | if (toDelete?.length) { 9 | for (const i of toDelete) { 10 | delete set[i]; 11 | } 12 | } 13 | 14 | return serializeCookie(set); 15 | } 16 | -------------------------------------------------------------------------------- /modules/backend-node/parse-set-cookie.test.ts: -------------------------------------------------------------------------------- 1 | import { parseSetCookie } from './parse-set-cookie'; 2 | 3 | test('parseSetCookie', () => { 4 | expect( 5 | parseSetCookie( 6 | 'visualJsid=f2e1a7eea23c4be0b33b5014762cf692; Path=/; HttpOnly, JSESSIONID=5981840E84A2A194A4D3A8937D664DF7; Path=/wd/visual; HttpOnly' 7 | ) 8 | ).toEqual({ 9 | JSESSIONID: '5981840E84A2A194A4D3A8937D664DF7', 10 | visualJsid: 'f2e1a7eea23c4be0b33b5014762cf692', 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /modules/backend-node/parse-set-cookie.ts: -------------------------------------------------------------------------------- 1 | import cookie from 'cookie'; 2 | 3 | export function parseSetCookie(str: string): Record { 4 | return cookie.parse( 5 | str 6 | .split(',') 7 | .map(i => { 8 | return i.split(';')[0].trim(); 9 | }) 10 | .join(';') 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /modules/backend-node/predicate.ts: -------------------------------------------------------------------------------- 1 | import { API_PREFIX } from './constants'; 2 | 3 | /** 4 | * 是否为后端服务路径 5 | * @param p 6 | * @returns 7 | */ 8 | export function isBackendPath(p: string) { 9 | return p.startsWith(API_PREFIX); 10 | } 11 | -------------------------------------------------------------------------------- /modules/backend-node/serialize-cookie.ts: -------------------------------------------------------------------------------- 1 | export function serializeCookie(cookies: Record): string { 2 | return Object.entries(cookies) 3 | .map(([key, value]) => { 4 | return `${key}=${value}`; 5 | }) 6 | .join('; '); 7 | } 8 | -------------------------------------------------------------------------------- /modules/chat-bot/BotButton.tsx: -------------------------------------------------------------------------------- 1 | import { ChatWindow } from '@/lib/chat-bot'; 2 | import { FloatButton } from 'antd'; 3 | import { BotIcon } from './BotIcon'; 4 | 5 | export const BotButton = () => { 6 | return ( 7 | 8 | } type="primary"> 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /modules/chat-bot/StandalonePage.module.scss: -------------------------------------------------------------------------------- 1 | .user { 2 | cursor: pointer; 3 | display: inline-flex; 4 | align-items: center; 5 | gap: 3px; 6 | color: var(--vd-color-gray-800); 7 | font-size: 12px; 8 | font-weight: bold; 9 | } 10 | -------------------------------------------------------------------------------- /modules/chat-bot/extensions/index.ts: -------------------------------------------------------------------------------- 1 | import { registerSubjectSummary } from '@/lib/chat-bot'; 2 | 3 | import './global'; 4 | // import './echo'; 5 | import './ddd-master'; 6 | // import './dall-e'; 7 | 8 | registerSubjectSummary(async text => { 9 | const res = await fetch('/api/rest/ai/subject', { 10 | method: 'POST', 11 | body: JSON.stringify({ text }), 12 | headers: { 13 | 'content-type': 'application/json', 14 | }, 15 | }); 16 | 17 | if (res.ok) { 18 | return await res.text(); 19 | } 20 | 21 | return ''; 22 | }); 23 | -------------------------------------------------------------------------------- /modules/chat-bot/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useChatSupported'; 2 | -------------------------------------------------------------------------------- /modules/chat-bot/hooks/useChatSupported.ts: -------------------------------------------------------------------------------- 1 | import { useRequestByGet } from '@/modules/backend-client'; 2 | 3 | export function useChatSupported() { 4 | const res = useRequestByGet('/api/rest/ai/chat-supported'); 5 | 6 | return res.data ?? false; 7 | } 8 | -------------------------------------------------------------------------------- /modules/document-layout/HeadingMenu.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: fixed; 3 | right: 0; 4 | top: var(--nav-height); 5 | bottom: 0; 6 | background-color: white; 7 | padding: var(--vd-spacing-sm); 8 | overflow: auto; 9 | } 10 | -------------------------------------------------------------------------------- /modules/document-layout/Navigation.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: sticky; 3 | top: 0; 4 | height: 100%; 5 | max-height: 100vh; 6 | overflow: hidden; 7 | border-right: 1px solid var(--vd-color-gray-300); 8 | 9 | padding: var(--vd-spacing-xs); 10 | } 11 | 12 | .menu { 13 | border-inline-end: none !important; 14 | } 15 | 16 | .title { 17 | font-size: var(--vd-font-size-h2); 18 | padding: var(--vd-spacing-xs); 19 | font-weight: bold; 20 | } 21 | -------------------------------------------------------------------------------- /modules/document-layout/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './Header'; 2 | export * from './Layout'; 3 | export * from './HeadingMenu'; 4 | export * from './Navigation'; 5 | -------------------------------------------------------------------------------- /modules/domain/Designer/Context.tsx: -------------------------------------------------------------------------------- 1 | import { useDesignerContext } from '@/lib/designer'; 2 | import { DomainDesignerModel } from './model'; 3 | 4 | export function useDomainDesignerContext() { 5 | return useDesignerContext(); 6 | } 7 | -------------------------------------------------------------------------------- /modules/domain/Designer/Loading/index.tsx: -------------------------------------------------------------------------------- 1 | import { DesignerLoading } from '@/lib/designer'; 2 | import { observer } from 'mobx-react'; 3 | 4 | import { useDomainDesignerContext } from '../Context'; 5 | 6 | export const DomainDesignerLoading = observer(function DomainDesignerLoading() { 7 | const model = useDomainDesignerContext(); 8 | 9 | return ; 10 | }); 11 | -------------------------------------------------------------------------------- /modules/domain/Designer/model/constants.ts: -------------------------------------------------------------------------------- 1 | export { DomainDesignerTabs, DomainDesignerTabsMap } from '../../constants'; 2 | -------------------------------------------------------------------------------- /modules/domain/Designer/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './DomainDesignerModel'; 3 | -------------------------------------------------------------------------------- /modules/domain/README.md: -------------------------------------------------------------------------------- 1 | # 业务域 2 | -------------------------------------------------------------------------------- /modules/domain/api/dsl/IObjectStore.ts: -------------------------------------------------------------------------------- 1 | import { Entity, ValueObject } from './domain-model'; 2 | import { DTO } from './query-model'; 3 | import { DataObject } from './data-model'; 4 | import { Node } from './shared'; 5 | 6 | export interface IObjectStore { 7 | getObjectById: (id: string) => { object: Entity | ValueObject | DTO | DataObject; parent?: Node }; 8 | } 9 | -------------------------------------------------------------------------------- /modules/domain/api/dsl/mapper-model.test.ts: -------------------------------------------------------------------------------- 1 | import {} from './mapper-model'; 2 | 3 | test('MapperModel', () => { 4 | // TODO: 5 | }); 6 | -------------------------------------------------------------------------------- /modules/domain/api/utils.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest } from 'next'; 2 | 3 | /** 4 | * 从 request 中 读取 buffer 5 | * @param req 6 | * @returns 7 | */ 8 | export async function readBuffer(req: NextApiRequest): Promise { 9 | return new Promise((resolve, reject) => { 10 | const list: any[] = []; 11 | req 12 | .on('data', data => { 13 | list.push(data); 14 | }) 15 | .on('end', () => { 16 | const buffer = Buffer.concat(list); 17 | resolve(buffer); 18 | }) 19 | .on('error', reject); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /modules/domain/data-design/StandaloneDataObjectEditor.tsx: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | 3 | export { StandaloneDataObjectEditor as default } from './components/StandaloneDataObjectEditor'; 4 | -------------------------------------------------------------------------------- /modules/domain/data-design/ai-dsl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './transform'; 2 | -------------------------------------------------------------------------------- /modules/domain/data-design/ai-import/index.ts: -------------------------------------------------------------------------------- 1 | export * from './transform'; 2 | -------------------------------------------------------------------------------- /modules/domain/data-design/ai-transformer/README.md: -------------------------------------------------------------------------------- 1 | # AI 数据对象操作 2 | -------------------------------------------------------------------------------- /modules/domain/data-design/bot-extension/dataObject/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dataObject'; 2 | -------------------------------------------------------------------------------- /modules/domain/data-design/bot-extension/index.ts: -------------------------------------------------------------------------------- 1 | // import { useDataObjectCreateBot } from './create'; 2 | import { useDataObjectBot } from './dataObject'; 3 | import { useDataObjectSqlMasterBot } from './sqlMaster'; 4 | 5 | export function useDataDesignBot() { 6 | // useDataObjectCreateBot(); 7 | useDataObjectSqlMasterBot(); 8 | useDataObjectBot(); 9 | } 10 | -------------------------------------------------------------------------------- /modules/domain/data-design/components/AIModal.module.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | background: linear-gradient(120deg, #3f94d6 30%, #1e62be); 3 | // -webkit-background-clip: text; 4 | // -webkit-text-fill-color: transparent; 5 | // font-weight: bolder; 6 | // font-size: 16px; 7 | color: white; 8 | font-size: 13px; 9 | height: 28px; 10 | line-height: 28px; 11 | border-radius: 10px; 12 | padding: 0 12px; 13 | position: absolute; 14 | cursor: pointer; 15 | right: 16px; 16 | top: 50%; 17 | transform: translateY(-50%); 18 | } 19 | -------------------------------------------------------------------------------- /modules/domain/data-design/components/ShapeTree.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/data-design/components/ShapeTree.module.scss -------------------------------------------------------------------------------- /modules/domain/data-design/components/StandaloneDataObjectEditor.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 100%; 3 | height: 50vh; 4 | min-height: 500px; 5 | overflow: hidden; 6 | } 7 | -------------------------------------------------------------------------------- /modules/domain/data-design/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DataObjectEditor'; 2 | -------------------------------------------------------------------------------- /modules/domain/data-design/dsl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dsl'; 2 | export * from './factory'; 3 | export * from './constants'; 4 | -------------------------------------------------------------------------------- /modules/domain/data-design/index.ts: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | 3 | export * from './components'; 4 | export * from './model'; 5 | export * from './factory'; 6 | -------------------------------------------------------------------------------- /modules/domain/data-design/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DataObjectEditorModel'; 2 | export * from './DataObject'; 3 | export * from './DataObjectStore'; 4 | -------------------------------------------------------------------------------- /modules/domain/data-design/shape/DataObject/PropertiesEditor.module.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | font-size: var(--vd-font-size-h6); 3 | font-weight: 400; 4 | } 5 | -------------------------------------------------------------------------------- /modules/domain/data-design/shape/DataObject/RequireRenderer.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | line-height: 1; 3 | font-weight: bold; 4 | color: var(--vd-color-danger-500); 5 | padding: 0 2px; 6 | font-size: 1.2em; 7 | } 8 | -------------------------------------------------------------------------------- /modules/domain/data-design/shape/DataObject/TypeRenderer.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | font-weight: bold; 3 | 4 | &:global(.error) { 5 | color: var(--vd-color-danger-400); 6 | } 7 | 8 | &:global(.link) { 9 | color: var(--vd-color-link); 10 | cursor: pointer; 11 | 12 | &:hover { 13 | color: var(--vd-color-link-hover); 14 | text-decoration: underline; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /modules/domain/data-design/shape/DataObject/data-object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/data-design/shape/DataObject/data-object.png -------------------------------------------------------------------------------- /modules/domain/data-design/shape/DataObject/reactify.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | line-height: 1.2; 4 | flex: 1; 5 | overflow: hidden; 6 | align-items: center; 7 | } 8 | 9 | .name { 10 | flex: 1; 11 | overflow: hidden; 12 | text-overflow: ellipsis; 13 | } 14 | -------------------------------------------------------------------------------- /modules/domain/data-design/shape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DataObject'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/README.md: -------------------------------------------------------------------------------- 1 | # 领域模型设计 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/StandaloneDomainEditor.tsx: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | 3 | export { StandaloneDomainEditor as default } from './components/StandaloneDomainEditor'; 4 | -------------------------------------------------------------------------------- /modules/domain/domain-design/bot-extension/index.ts: -------------------------------------------------------------------------------- 1 | import { useWakeadminFormBot } from './wakeadmin-form'; 2 | import { useWakeadminTableBot } from './wakeadmin-table'; 3 | 4 | export function useBotExtension() { 5 | useWakeadminTableBot(); 6 | useWakeadminFormBot(); 7 | } 8 | -------------------------------------------------------------------------------- /modules/domain/domain-design/components/RelationShipSelect/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | height: 100%; 4 | align-items: center; 5 | position: absolute; 6 | right: var(--vd-spacing-sm); 7 | top: 0; 8 | } 9 | 10 | .value { 11 | color: var(--vd-color-font-secondary); 12 | margin-left: 4px; 13 | cursor: pointer; 14 | } 15 | 16 | .checkbox { 17 | display: flex; 18 | flex-direction: column; 19 | align-items: center; 20 | 21 | & > label { 22 | margin-left: 0 !important; 23 | } 24 | } 25 | 26 | .item { 27 | display: flex; 28 | align-items: center; 29 | } 30 | -------------------------------------------------------------------------------- /modules/domain/domain-design/components/ShapeTitle/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/components/ShapeTitle/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/components/StandaloneDomainEditor.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | width: 100%; 3 | height: 50vh; 4 | min-height: 500px; 5 | overflow: hidden; 6 | } 7 | -------------------------------------------------------------------------------- /modules/domain/domain-design/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DomainEditor'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/AccessSelect.tsx: -------------------------------------------------------------------------------- 1 | import { Select, SelectProps } from 'antd'; 2 | import { AccessList } from '../constants'; 3 | 4 | export const AccessSelect = (props: SelectProps) => { 5 | return ( 6 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/ClassShape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ClassShape'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/DescriptionInput/index.tsx: -------------------------------------------------------------------------------- 1 | export * from '@/lib/components/DescriptionInput'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/MemberList/MemberEditor.module.scss: -------------------------------------------------------------------------------- 1 | @keyframes flash { 2 | 0%, 3 | 50%, 4 | to { 5 | outline: 2px solid var(--vd-color-primary-500); 6 | } 7 | 8 | 25%, 9 | 75% { 10 | outline: 2px solid transparent; 11 | } 12 | } 13 | 14 | .root { 15 | &:global(.entering) { 16 | animation: flash 2s ease; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/MemberList/README.md: -------------------------------------------------------------------------------- 1 | # 可排序的成员列表 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/MemberList/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MemberList'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/MethodsEditor/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/dsl/components/MethodsEditor/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/NameInput/index.tsx: -------------------------------------------------------------------------------- 1 | export { NameInput } from '@/lib/components/NameInput'; 2 | export type { NameInputProps } from '@/lib/components/NameInput'; 3 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/ObjectNameInput/index.tsx: -------------------------------------------------------------------------------- 1 | import { observer } from 'mobx-react'; 2 | import { NameInputProps, NameInput } from '../NameInput'; 3 | 4 | export interface ObjectNameInputProps extends NameInputProps {} 5 | 6 | export const ObjectNameInput = observer(function ObjectNameInput(props: ObjectNameInputProps) { 7 | return ; 8 | }); 9 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/ParameterEditor/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/dsl/components/ParameterEditor/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/PropertiesEditor/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/dsl/components/PropertiesEditor/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/ReferenceTypeDisplay/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | color: var(--vd-color-link); 3 | text-decoration: underline; 4 | cursor: pointer; 5 | 6 | &:hover { 7 | color: var(--vd-color-link-hover); 8 | } 9 | } 10 | 11 | .error { 12 | color: var(--vd-color-danger-400); 13 | font-weight: bold; 14 | 15 | :global(.anticon) { 16 | margin-right: 2px; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/SourceInput/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: flex-start; 5 | 6 | & > label { 7 | margin-inline-start: 0 !important; 8 | margin-bottom: 4px; 9 | width: 100%; 10 | 11 | & > span:nth-child(2) { 12 | flex: 1; 13 | } 14 | } 15 | } 16 | 17 | .row { 18 | display: flex; 19 | align-items: center; 20 | width: 100%; 21 | 22 | & > :global(span) { 23 | width: 65px; 24 | flex-shrink: 0; 25 | } 26 | 27 | & > :global(.ant-input) { 28 | flex: 1; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/TitleInput/index.tsx: -------------------------------------------------------------------------------- 1 | export * from '@/lib/components/TitleInput'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/TypeInput/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './TypeInput'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/components/index.ts: -------------------------------------------------------------------------------- 1 | // 基础表单 2 | export * from './AccessSelect'; 3 | export * from './NameInput'; 4 | export * from './DescriptionInput'; 5 | export * from './TypeInput'; 6 | export * from './TitleInput'; 7 | export * from './SourceInput'; 8 | 9 | // 列表 10 | export * from './MemberList'; 11 | export * from './PropertiesEditor'; 12 | export * from './MethodsEditor'; 13 | export * from './ParameterEditor'; 14 | 15 | // 基础图形 16 | export * from './ClassShape'; 17 | -------------------------------------------------------------------------------- /modules/domain/domain-design/dsl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dsl'; 2 | export * from './factory'; 3 | export * from './validators'; 4 | export * from './constants'; 5 | export * from './components'; 6 | export * from './stringify'; 7 | export * from './reactify'; 8 | export * from './dependency'; 9 | -------------------------------------------------------------------------------- /modules/domain/domain-design/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useAutoCompleteUbiquitousLanguageFromFormModel'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/hooks/useAutoCompleteUbiquitousLanguageFromFormModel.ts: -------------------------------------------------------------------------------- 1 | import { useAutoCompleteUbiquitousLanguage } from '@/lib/components/NameInput'; 2 | import { useEditorFormContext } from '@/lib/editor'; 3 | 4 | export function useAutoCompleteUbiquitousLanguageFromFormModel(options: { 5 | path: string; 6 | titleName?: string; 7 | descriptionName?: string; 8 | }) { 9 | const { formModel } = useEditorFormContext()!; 10 | 11 | return useAutoCompleteUbiquitousLanguage({ 12 | ...options, 13 | setter: (path: string, value: string) => formModel.setProperty(path, value), 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /modules/domain/domain-design/index.ts: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | 3 | export * from './components'; 4 | export * from './model'; 5 | export * from './factory'; 6 | -------------------------------------------------------------------------------- /modules/domain/domain-design/model/DomainObjectValueObject.ts: -------------------------------------------------------------------------------- 1 | import { ValueObjectDSL } from '../dsl'; 2 | 3 | import { DomainObjectClass } from './DomainObjectClass'; 4 | 5 | export class DomainObjectValueObject extends DomainObjectClass { 6 | override get objectTypeTitle() { 7 | return '值对象'; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /modules/domain/domain-design/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DomainEditorModel'; 2 | export * from './DomainObject'; 3 | export * from './DomainObjectStore'; 4 | export * from './DomainObjectAggregation'; 5 | export * from './DomainObjectCommand'; 6 | export * from './DomainObjectEnum'; 7 | export * from './DomainObjectEntity'; 8 | export * from './DomainObjectValueObject'; 9 | export * from './DomainObjectRule'; 10 | export * from './DomainObjectFactory'; 11 | export * from './DomainObjectUnderAggregation'; 12 | export * from './DomainObjectDTO'; 13 | export * from './DomainObjectQuery'; 14 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Aggregation/aggregation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Aggregation/aggregation.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Command/CommandEditor/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Command/CommandEditor/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Command/CommandShape/CommandShape.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | } 3 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Command/CommandShape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CommandShape'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Command/command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Command/command.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Command/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Command'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/DTO/dto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/DTO/dto.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/DTO/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DTO'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Entity/entity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Entity/entity.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Enum/EnumEditor/EnumMembersEditor/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Enum/EnumEditor/EnumMembersEditor/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Enum/EnumShape/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | background-color: #e7d4ff; 3 | } 4 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Enum/enum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Enum/enum.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Enum/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Enum'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Query/QueryEditor/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Query/QueryEditor/index.module.scss -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Query/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Query'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Query/query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Query/query.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/README.md: -------------------------------------------------------------------------------- 1 | # 领域建模图形 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Rule/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Rule'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/Rule/rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/Rule/rule.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/ValueObject/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ValueObject'; 2 | -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/ValueObject/value-object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/domain-design/shape/ValueObject/value-object.png -------------------------------------------------------------------------------- /modules/domain/domain-design/shape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Entity'; 2 | export * from './ValueObject'; 3 | export * from './Aggregation'; 4 | export * from './Command'; 5 | export * from './Rule'; 6 | export * from './Enum'; 7 | export * from './DTO'; 8 | export * from './Query'; 9 | -------------------------------------------------------------------------------- /modules/domain/generator/BaseGeneratorState.ts: -------------------------------------------------------------------------------- 1 | import { assert } from '@/lib/utils'; 2 | import { NameDSL } from '../domain-design/dsl/dsl'; 3 | import { IGeneratorState } from './types'; 4 | 5 | export class BaseGeneratorState implements IGeneratorState { 6 | list: T[] = []; 7 | 8 | results: Map = new Map(); 9 | 10 | save(uuid: string, result: T) { 11 | assert(!this.results.has(uuid), 'uuid 重复'); 12 | 13 | this.list.push(result); 14 | this.results.set(uuid, result); 15 | } 16 | 17 | get(uuid: string): T | undefined { 18 | return this.results.get(uuid); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /modules/domain/generator/FromEnumDSLGenerator.ts: -------------------------------------------------------------------------------- 1 | import { enumToTypeDSL } from '../domain-design/dsl'; 2 | import { EnumDSL, TypeDSL } from '../domain-design/dsl/dsl'; 3 | 4 | export class FromEnumDSLGenerator { 5 | private enum: EnumDSL; 6 | 7 | constructor(inject: { enum: EnumDSL }) { 8 | this.enum = inject.enum; 9 | } 10 | 11 | toTypeDSL(): TypeDSL { 12 | return enumToTypeDSL(this.enum); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /modules/domain/generator/README.md: -------------------------------------------------------------------------------- 1 | # 自动生成器 2 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/README.md: -------------------------------------------------------------------------------- 1 | # 结构化对象映射 2 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MapperEditor'; 2 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/dsl/constants.ts: -------------------------------------------------------------------------------- 1 | export enum MapperObjectName { 2 | MapperObject = 'mapperObject', 3 | } 4 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/dsl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dsl'; 2 | export * from './factory'; 3 | export * from './constants'; 4 | export * from './compatible'; 5 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/factory.ts: -------------------------------------------------------------------------------- 1 | import { BuiltinShapeName } from '@/lib/editor'; 2 | import { MapperObjectName } from './dsl'; 3 | import { MapperEditorModel, MapperEditorModelOptions } from './model'; 4 | 5 | /** 6 | * 模型构造 7 | * @param options 8 | * @returns 9 | */ 10 | export function createMapperEditorModel( 11 | options: Omit 12 | ) { 13 | const shapeList = [MapperObjectName.MapperObject, BuiltinShapeName.Comment]; 14 | const whitelist = shapeList; 15 | 16 | return new MapperEditorModel({ ...options, scopeId: 'mapper', shapeList, whitelist, activeScope: false }); 17 | } 18 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/index.ts: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | 3 | export * from './factory'; 4 | export * from './model'; 5 | export * from './components'; 6 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/model/IFieldMapper.ts: -------------------------------------------------------------------------------- 1 | import { PropertyDSL } from '@/modules/domain/domain-design/dsl'; 2 | import { DataObjectPropertyDSL } from '@/modules/domain/data-design/dsl'; 3 | 4 | import { FieldMapperDSL } from '../dsl'; 5 | 6 | export interface IFieldMapper extends FieldMapperDSL { 7 | sourceProperty?: PropertyDSL; 8 | targetProperty?: DataObjectPropertyDSL; 9 | } 10 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/model/ISourceObject.ts: -------------------------------------------------------------------------------- 1 | import { NameDSL, PropertyDSL } from '@/modules/domain/domain-design/dsl'; 2 | 3 | /** 4 | * 来源对象 5 | * 6 | * 可以是领域对象、DTO 7 | * 字段类型为 Java 8 | * 9 | */ 10 | export interface ISourceObject extends NameDSL { 11 | /** 12 | * 属性 13 | */ 14 | properties: PropertyDSL[]; 15 | } 16 | 17 | export interface ISourceObjectGroup { 18 | key: string; 19 | label: string; 20 | list: ISourceObject[]; 21 | } 22 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/model/ITargetObject.ts: -------------------------------------------------------------------------------- 1 | import { NameDSL } from '@/modules/domain/domain-design/dsl'; 2 | import { DataObjectPropertyDSL } from '@/modules/domain/data-design/dsl'; 3 | 4 | /** 5 | * 目标对象 6 | * 通常为数据模型 7 | */ 8 | export interface ITargetObject extends NameDSL { 9 | properties: DataObjectPropertyDSL[]; 10 | } 11 | 12 | export interface ITargetObjectGroup { 13 | key: string; 14 | label: string; 15 | list: ITargetObject[]; 16 | } 17 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MapperEditorModel'; 2 | export * from './MapperStore'; 3 | export * from './IFieldMapper'; 4 | export * from './ISourceObject'; 5 | export * from './ITargetObject'; 6 | export * from './Mapper'; 7 | export * from './IObjectStore'; 8 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/FieldMapperDisplay.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.anticon) { 3 | color: gray; 4 | margin: 0 4px; 5 | } 6 | } 7 | 8 | .type { 9 | color: var(--vd-color-gray-500); 10 | } 11 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/ObjectMapperDisplay.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.anticon) { 3 | color: gray; 4 | margin: 0 4px; 5 | } 6 | 7 | display: flex; 8 | gap: 6px; 9 | } 10 | 11 | .object { 12 | display: flex; 13 | align-items: center; 14 | line-height: 1.8; 15 | max-width: 16em; 16 | 17 | .modifier { 18 | color: var(--vd-color-gray-500); 19 | margin-left: 4px; 20 | white-space: nowrap; 21 | flex-shrink: 0; 22 | } 23 | 24 | .name { 25 | flex: 1; 26 | font-weight: 600; 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/Shape.module.scss: -------------------------------------------------------------------------------- 1 | .property { 2 | text-align: center; 3 | } 4 | 5 | .name { 6 | text-overflow: ellipsis; 7 | overflow: hidden; 8 | max-width: 100%; 9 | } 10 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/Title.tsx: -------------------------------------------------------------------------------- 1 | import { NameDSL, UntitledInHumanReadable, UntitledInUpperCamelCase } from '@/modules/domain/domain-design/dsl'; 2 | import { observer } from 'mobx-react'; 3 | 4 | export interface TitleProps { 5 | value: NameDSL; 6 | } 7 | 8 | export const Title = observer(function Title(props: TitleProps) { 9 | const { value } = props; 10 | return {`${value.title || UntitledInHumanReadable}(${value.name || UntitledInUpperCamelCase})`}; 11 | }); 12 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/mapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/mapper-design/shape/Mapper/mapper.png -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/reactify.tsx: -------------------------------------------------------------------------------- 1 | import { Mapper } from '../../model'; 2 | 3 | import { FieldMapperDisplay } from './FieldMapperDisplay'; 4 | 5 | export function reactifyMapper(sourceFieldId: string | undefined, targetFieldId: string | undefined, mapper: Mapper) { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/Mapper/useMapper.ts: -------------------------------------------------------------------------------- 1 | import { useEditorFormContext, useEditorModel } from '@/lib/editor'; 2 | import { MapperEditorModel } from '../../model'; 3 | 4 | /** 5 | * 获取 mapper 模型 6 | * @returns 7 | */ 8 | export function useMapper() { 9 | const { model } = useEditorModel(); 10 | const { formModel } = useEditorFormContext()!; 11 | 12 | return model.mapperStore.getMapperById(formModel.id)!; 13 | } 14 | -------------------------------------------------------------------------------- /modules/domain/mapper-design/shape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Mapper'; 2 | -------------------------------------------------------------------------------- /modules/domain/query-design/README.md: -------------------------------------------------------------------------------- 1 | # 查询模型编辑器 2 | -------------------------------------------------------------------------------- /modules/domain/query-design/index.ts: -------------------------------------------------------------------------------- 1 | export * from './factory'; 2 | -------------------------------------------------------------------------------- /modules/domain/transform/DTO.ts: -------------------------------------------------------------------------------- 1 | import { DTODSL } from '../domain-design/dsl/dsl'; 2 | 3 | import { ClassLike } from './ClassLike'; 4 | 5 | export class DTO extends ClassLike {} 6 | -------------------------------------------------------------------------------- /modules/domain/transform/Query.ts: -------------------------------------------------------------------------------- 1 | import { QueryDSL } from '../domain-design/dsl/dsl'; 2 | 3 | import { PropertiesLike } from './PropertiesLike'; 4 | 5 | export class Query extends PropertiesLike { 6 | override toQuery(): QueryDSL { 7 | return this.clone(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /modules/domain/transform/README.md: -------------------------------------------------------------------------------- 1 | # 对象之间转换 2 | 3 | 涉及到领域模型、数据模型、查询模型之间的转换,因此将模块提取到这里 4 | -------------------------------------------------------------------------------- /modules/domain/transform/ValueObject.ts: -------------------------------------------------------------------------------- 1 | import { ValueObjectDSL } from '../domain-design/dsl/dsl'; 2 | 3 | import { ClassLike } from './ClassLike'; 4 | 5 | export class ValueObject extends ClassLike {} 6 | -------------------------------------------------------------------------------- /modules/domain/ubiquitous-language-design/AIImport.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.ant-modal-body) { 3 | max-height: 80vh; 4 | overflow: auto; 5 | } 6 | } 7 | 8 | .text { 9 | margin-bottom: 1em; 10 | } 11 | 12 | .words { 13 | margin-top: 2em; 14 | } 15 | 16 | .tags { 17 | margin-bottom: 1.5em; 18 | display: flex; 19 | flex-wrap: wrap; 20 | row-gap: 8px; 21 | column-gap: 0px; 22 | } 23 | 24 | .customTag { 25 | display: inline-block; 26 | width: 120px; 27 | } 28 | -------------------------------------------------------------------------------- /modules/domain/ubiquitous-language-design/List.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: 37px; 3 | } 4 | 5 | .search { 6 | width: 20em; 7 | } 8 | 9 | .table { 10 | margin-bottom: var(--vd-spacing-xs); 11 | } 12 | 13 | .actions { 14 | display: flex; 15 | align-items: center; 16 | justify-content: space-between; 17 | margin-bottom: var(--vd-spacing-sm); 18 | } 19 | 20 | .item { 21 | border: 1px solid transparent; 22 | min-height: 24px; 23 | padding: 0 7px; 24 | width: 100%; 25 | border-radius: 4px; 26 | cursor: text; 27 | 28 | &:global(.editable):hover { 29 | border: 1px solid var(--vd-color-gray-500); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /modules/domain/ubiquitous-language-design/README.md: -------------------------------------------------------------------------------- 1 | # 统一语言 2 | -------------------------------------------------------------------------------- /modules/domain/ubiquitous-language-design/Yjs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ItemWrapper'; 2 | export * from './Builder'; 3 | -------------------------------------------------------------------------------- /modules/domain/ubiquitous-language-design/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './List'; 2 | export { UbiquitousLanguageModel } from './UbiquitousLanguageModel'; 3 | -------------------------------------------------------------------------------- /modules/domain/vision-design/VisionDesign.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | padding: 37px; 3 | } 4 | 5 | .header { 6 | font-weight: bold; 7 | } 8 | 9 | .body { 10 | display: flex; 11 | flex-wrap: wrap; 12 | gap: 37px; 13 | margin-top: var(--vd-spacing-sm); 14 | } 15 | 16 | .example, 17 | .content { 18 | flex: 1; 19 | } 20 | 21 | .example { 22 | display: flex; 23 | flex-direction: column; 24 | } 25 | 26 | .img { 27 | width: 100%; 28 | height: auto; 29 | } 30 | -------------------------------------------------------------------------------- /modules/domain/vision-design/example-ou.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/domain/vision-design/example-ou.png -------------------------------------------------------------------------------- /modules/domain/vision-design/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './VisionDesign'; 2 | -------------------------------------------------------------------------------- /modules/home/pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/home/pic.png -------------------------------------------------------------------------------- /modules/not-found/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | flex-direction: column; 4 | min-height: 100vh; 5 | width: 100%; 6 | align-items: center; 7 | justify-content: center; 8 | } 9 | 10 | .logo { 11 | font-size: 150px; 12 | } 13 | 14 | .code { 15 | font-size: 40px; 16 | font-weight: bold; 17 | } 18 | 19 | .message { 20 | margin-top: 18px; 21 | font-size: 16px; 22 | color: var(--vd-color-gray-800); 23 | } 24 | 25 | .actions { 26 | margin-top: 20px; 27 | display: flex; 28 | gap: var(--vd-spacing-xs); 29 | } 30 | -------------------------------------------------------------------------------- /modules/organization/Organization/TeamMember.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.ant-pro-card-body) { 3 | padding: 0; 4 | } 5 | } 6 | 7 | .add { 8 | } 9 | 10 | .userSelect { 11 | width: 12em; 12 | margin-top: var(--vd-spacing-sm); 13 | margin-right: var(--vd-spacing-xs); 14 | } 15 | -------------------------------------------------------------------------------- /modules/organization/Organization/UpdateTeam.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.ant-modal-body) { 3 | height: 50vh; 4 | } 5 | } 6 | 7 | .tabs { 8 | height: 100%; 9 | } 10 | 11 | .base { 12 | } 13 | -------------------------------------------------------------------------------- /modules/organization/Organization/index.module.scss: -------------------------------------------------------------------------------- 1 | .memberSelect { 2 | width: 200px; 3 | margin-right: var(--vd-border-radius-md); 4 | } 5 | -------------------------------------------------------------------------------- /modules/redis/index.ts: -------------------------------------------------------------------------------- 1 | import { RedisClientType, createClient } from 'redis'; 2 | 3 | const url = process.env.REDIS; 4 | 5 | let client: RedisClientType | undefined; 6 | 7 | /** 8 | * 获取 redis 客户端 9 | * @returns 10 | */ 11 | export function getRedisClient() { 12 | if (client) { 13 | return client; 14 | } 15 | 16 | if (url) { 17 | return (client = createClient({ 18 | url, 19 | })); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /modules/scenario/Designer/Context.tsx: -------------------------------------------------------------------------------- 1 | import { ScenarioDesignerModel } from './model'; 2 | import { useDesignerContext } from '@/lib/designer'; 3 | 4 | export function useScenarioDesignerContext() { 5 | return useDesignerContext(); 6 | } 7 | -------------------------------------------------------------------------------- /modules/scenario/Designer/model/constants.ts: -------------------------------------------------------------------------------- 1 | import { ScenarioDesignerTabs } from '@/modules/scenario/constants'; 2 | 3 | export { ScenarioDesignerTabs } from '@/modules/scenario/constants'; 4 | 5 | export const ScenarioDesignerTabsMap = { 6 | [ScenarioDesignerTabs.Scenario]: '业务流程', 7 | [ScenarioDesignerTabs.Service]: '服务模型', 8 | }; 9 | -------------------------------------------------------------------------------- /modules/scenario/Designer/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './ScenarioDesignerModel'; 3 | -------------------------------------------------------------------------------- /modules/scenario/README.md: -------------------------------------------------------------------------------- 1 | # 业务场景 2 | -------------------------------------------------------------------------------- /modules/scenario/api/dsl/__snapshots__/scenario-model.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`scenario-model 1`] = ` 4 | { 5 | "domainDependencies": [ 6 | { 7 | "domainId": 32, 8 | "serviceId": "51772af6-eb77-4ebe-82d5-53edcb7fe82c", 9 | "versionId": 60, 10 | }, 11 | { 12 | "domainId": 32, 13 | "serviceId": "93a15900-45d9-4804-a9e0-bf31a16009c0", 14 | "versionId": 60, 15 | }, 16 | ], 17 | "externalDependencies": [ 18 | { 19 | "description": "description", 20 | "name": "name", 21 | }, 22 | ], 23 | } 24 | `; 25 | -------------------------------------------------------------------------------- /modules/scenario/api/dsl/doc.test.ts: -------------------------------------------------------------------------------- 1 | import { createDoc } from './doc'; 2 | import * as mockedUuid from 'uuid'; 3 | 4 | jest.mock('uuid', () => { 5 | let count = 0; 6 | return { 7 | __esModule: true, 8 | reset() { 9 | count = 0; 10 | }, 11 | v4() { 12 | return `uuid-${count++}`; 13 | }, 14 | }; 15 | }); 16 | 17 | const mockedUuidModule = mockedUuid as unknown as jest.Mocked<{ reset(): void }>; 18 | 19 | beforeEach(() => { 20 | mockedUuidModule.reset(); 21 | }); 22 | 23 | test('createDoc', () => { 24 | const doc = createDoc(); 25 | 26 | expect(doc.toJSON()).toMatchSnapshot(); 27 | }); 28 | -------------------------------------------------------------------------------- /modules/scenario/api/dsl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './doc'; 2 | -------------------------------------------------------------------------------- /modules/scenario/api/utils.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest } from 'next'; 2 | 3 | /** 4 | * 从 request 中 读取 buffer 5 | * @param req 6 | * @returns 7 | */ 8 | export async function readBuffer(req: NextApiRequest): Promise { 9 | return new Promise((resolve, reject) => { 10 | const list: any[] = []; 11 | req 12 | .on('data', data => { 13 | list.push(data); 14 | }) 15 | .on('end', () => { 16 | const buffer = Buffer.concat(list); 17 | resolve(buffer); 18 | }) 19 | .on('error', reject); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /modules/scenario/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * YJS 字段 3 | */ 4 | export enum YJS_FIELD_NAME { 5 | /** 6 | * 业务流程 7 | */ 8 | SCENARIO = 'scenario', 9 | 10 | /** 11 | * 服务模型 12 | */ 13 | SERVICE = 'service', 14 | } 15 | 16 | /** 17 | * 标签页 18 | */ 19 | export enum ScenarioDesignerTabs { 20 | Scenario = 'scenario', 21 | Service = 'service', 22 | } 23 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/README.md: -------------------------------------------------------------------------------- 1 | # 业务场景设计 2 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/StandaloneEditor.tsx: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | export { ScenarioStandalone as default } from './components'; 3 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/ai-transformer/index.ts: -------------------------------------------------------------------------------- 1 | import { AITransformerParseError } from '@/lib/ai-directive-parser'; 2 | import { Executor, IFlowStore } from './executor'; 3 | import { parse } from './parser'; 4 | 5 | export * from './protocol'; 6 | export type { IFlowStore } from './executor'; 7 | 8 | export function scenarioAITransformer(input: string, store: IFlowStore) { 9 | const directives = parse(input); 10 | 11 | if (directives == null) { 12 | throw new AITransformerParseError('解析失败'); 13 | } 14 | 15 | const executor = new Executor({ store }); 16 | 17 | return executor.execute(directives); 18 | } 19 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/bot-extensions/index.ts: -------------------------------------------------------------------------------- 1 | import { useScenarioBot } from './scenario'; 2 | 3 | export function useBot() { 4 | useScenarioBot(); 5 | } 6 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/components/ScenarioStandalone.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | height: 100%; 3 | width: 100%; 4 | min-height: 500px; 5 | overflow: hidden; 6 | } 7 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ScenarioEditor'; 2 | export * from './ScenarioStandalone'; 3 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/dsl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './factory'; 3 | export * from './dsl'; 4 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/index.ts: -------------------------------------------------------------------------------- 1 | import './shape'; 2 | export * from './components'; 3 | export * from './model'; 4 | export * from './factory'; 5 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/model/IServiceStore.ts: -------------------------------------------------------------------------------- 1 | import type { NameDSL } from '@/modules/domain/domain-design/dsl'; 2 | 3 | export interface IServiceStore { 4 | /** 5 | * 服务列表 6 | */ 7 | list: NameDSL[]; 8 | 9 | /** 10 | * 通过 id 获取服务 11 | * @param id 12 | */ 13 | getObjectById(id: string): NameDSL | undefined; 14 | 15 | /** 16 | * 打开服务 17 | * @param id 18 | */ 19 | openObjectById(id: string): void; 20 | } 21 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/model/ScenarioValidateManager.ts: -------------------------------------------------------------------------------- 1 | import { BaseEditorEvent, BaseEditorModel, BaseEditorValidateManager } from '@/lib/editor'; 2 | 3 | export class ScenarioValidateManager extends BaseEditorValidateManager { 4 | private event: BaseEditorEvent; 5 | 6 | constructor(inject: { event: BaseEditorEvent; editorModel: BaseEditorModel }) { 7 | super(inject); 8 | 9 | this.event = inject.event; 10 | 11 | this.eventHandler(); 12 | } 13 | 14 | private eventHandler() { 15 | this.event.on('NODE_UNACTIVE', evt => { 16 | const { node } = evt; 17 | 18 | this.checkFull(node.id); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ScenarioEditorModel'; 2 | export * from './IServiceStore'; 3 | export * from './IDomainServiceStore'; 4 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Activity/DomainServiceEditor.module.scss: -------------------------------------------------------------------------------- 1 | .tag { 2 | color: var(--vd-color-font-regular) !important; 3 | white-space: pre-wrap !important; 4 | word-break: break-all; 5 | margin: 3px; 6 | 7 | :global(.ant-tag-close-icon) { 8 | color: var(--vd-color-font-primary) !important; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Activity/ScenarioServiceSelect.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/scenario/scenario-design/shape/Activity/ScenarioServiceSelect.module.scss -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Activity/activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/scenario/scenario-design/shape/Activity/activity.png -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Activity/common.module.scss: -------------------------------------------------------------------------------- 1 | .share { 2 | font-size: 1em; 3 | line-height: 1em !important; 4 | vertical-align: middle; 5 | margin-left: 3px; 6 | color: var(--vd-color-link); 7 | cursor: pointer; 8 | 9 | &:hover { 10 | color: var(--vd-color-link-hover); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Comment/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/scenario/scenario-design/shape/Comment/comment.png -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Decision/decision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/scenario/scenario-design/shape/Decision/decision.png -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Decision/index.module.scss: -------------------------------------------------------------------------------- 1 | $width: 75px; 2 | 3 | .root { 4 | width: $width; 5 | height: $width; 6 | background-color: var(--vd-color-warning-200); 7 | border: 2px solid var(--vd-color-warning-400); 8 | border-radius: 4px; 9 | transform: rotate(45deg) scale(0.8); 10 | transform-origin: center; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | } 15 | 16 | .name { 17 | display: block; 18 | width: 100%; 19 | text-align: center; 20 | transform: rotate(-45deg); 21 | color: var(--vd-color-gray-800); 22 | } 23 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/End/end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/scenario/scenario-design/shape/End/end.png -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/End/index.module.scss: -------------------------------------------------------------------------------- 1 | $width: 45px; 2 | 3 | .root { 4 | width: $width; 5 | height: $width; 6 | border-radius: $width; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | border: 5px solid var(--vd-color-gray-700); 11 | background-color: var(--vd-color-gray-400); 12 | } 13 | 14 | .icon { 15 | width: 20px; 16 | height: 20px; 17 | background-color: white; 18 | border-radius: 5px; 19 | } 20 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/LabelEdge/Label.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | position: absolute; 3 | transform: translate(-50%, -50%); 4 | background-color: white; 5 | font-size: 12px; 6 | line-height: 1; 7 | padding: 2px 8px; 8 | border: 2px solid var(--vd-color-gray-600); 9 | border-radius: 12px; 10 | white-space: nowrap; 11 | max-width: 10em; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | } 15 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Lane/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 拖拽时预留的间隔 3 | */ 4 | export const GAP = 40; 5 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Lane/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './register'; 2 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Start/index.module.scss: -------------------------------------------------------------------------------- 1 | $width: 45px; 2 | 3 | .root { 4 | width: $width; 5 | height: $width; 6 | border-radius: $width; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | border: 5px solid var(--vd-color-success-700); 11 | background-color: var(--vd-color-success-200); 12 | 13 | font-size: 20px; 14 | color: white; 15 | 16 | & > svg { 17 | margin-left: -1px; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/Start/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/scenario/scenario-design/shape/Start/start.png -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './Lane'; 2 | export * from './Start'; 3 | export * from './End'; 4 | export * from './Activity'; 5 | export * from './Decision'; 6 | export * from './Comment'; 7 | export * from './NormalEdge'; 8 | export * from './LabelEdge'; 9 | export * from './CommentEdge'; 10 | -------------------------------------------------------------------------------- /modules/scenario/scenario-design/shape/shared.module.scss: -------------------------------------------------------------------------------- 1 | .port { 2 | &:hover { 3 | fill: var(--vd-color-primary); 4 | opacity: 1 !important; 5 | transform: scale(1.1); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /modules/scenario/service-design/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@/modules/domain/domain-design/index'; 2 | export * from './factory'; 3 | -------------------------------------------------------------------------------- /modules/session/README.md: -------------------------------------------------------------------------------- 1 | # 会话信息 2 | -------------------------------------------------------------------------------- /modules/session/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from './login'; 2 | export * from './logout'; 3 | export * from './update-entry'; 4 | export * from './session'; 5 | export * from './device-check'; 6 | -------------------------------------------------------------------------------- /modules/session/api/logout.ts: -------------------------------------------------------------------------------- 1 | import { allowMethod } from '@/lib/api'; 2 | import { createSuccessResponse } from '@/modules/backend-node'; 3 | import { withIronSessionApiRoute } from 'iron-session/next'; 4 | 5 | import { IRON_SESSION_OPTIONS } from '../config'; 6 | import { removeStateByRequest } from './device-check'; 7 | 8 | /** 9 | * 退出登录 10 | */ 11 | export const logout = allowMethod( 12 | 'POST', 13 | withIronSessionApiRoute(async (req, res) => { 14 | removeStateByRequest(req); 15 | req.session.destroy(); 16 | res.status(200).json(createSuccessResponse(null)); 17 | }, IRON_SESSION_OPTIONS) 18 | ); 19 | -------------------------------------------------------------------------------- /modules/session/api/utils.ts: -------------------------------------------------------------------------------- 1 | import gravatarUrl from 'gravatar-url'; 2 | import memoize from 'lodash/memoize'; 3 | 4 | export const getGravatarUrl = memoize((mail: string) => { 5 | const url = gravatarUrl(mail, { 6 | size: 200, 7 | }); 8 | 9 | // 使用七牛云 10 | return url.replace('gravatar.com', 'dn-qiniu-avatar.qbox.me'); 11 | }); 12 | -------------------------------------------------------------------------------- /modules/session/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useSession'; 2 | export * from './useLogout'; 3 | export * from './useDeviceCheck'; 4 | -------------------------------------------------------------------------------- /modules/session/hooks/useLogout.ts: -------------------------------------------------------------------------------- 1 | import { request, useCleanRequestCache } from '@/modules/backend-client'; 2 | import { useRouter } from 'next/router'; 3 | 4 | /** 5 | * 退出登录 6 | * @returns 7 | */ 8 | export function useLogout() { 9 | const router = useRouter(); 10 | const cleanSWRCache = useCleanRequestCache(); 11 | 12 | const logout = async () => { 13 | await request.requestByPost('/api/logout'); 14 | 15 | cleanSWRCache(); 16 | 17 | router.push('/login'); 18 | }; 19 | 20 | return logout; 21 | } 22 | -------------------------------------------------------------------------------- /modules/session/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 视图端 API 3 | */ 4 | export * from './types'; 5 | export * from './hooks'; 6 | -------------------------------------------------------------------------------- /modules/session/server.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 纯服务端 API 3 | */ 4 | export * from './types'; 5 | export * from './api-helper'; 6 | export * from './ssr-helper'; 7 | export * from './api'; 8 | -------------------------------------------------------------------------------- /modules/storage/ICacheStorage.ts: -------------------------------------------------------------------------------- 1 | export interface ICacheStorage { 2 | /** 3 | * 注意 expired 是一个时间戳(ms), 表示过期的时间点,可能为 Infinity 4 | */ 5 | set(key: string, value: T, expired?: number): Promise; 6 | get(key: string): Promise; 7 | has(key: string): Promise; 8 | delete(key: string): Promise; 9 | } 10 | -------------------------------------------------------------------------------- /modules/storage/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CacheContainer'; 2 | export * from './CacheStorageInMemory'; 3 | export * from './CacheStorageInRedis'; 4 | export * from './ICacheStorage'; 5 | export * from './utils'; 6 | -------------------------------------------------------------------------------- /modules/system/README.md: -------------------------------------------------------------------------------- 1 | # 系统管理 2 | -------------------------------------------------------------------------------- /modules/team/App/Association/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | :global(.ant-modal-body) { 3 | max-height: 70vh; 4 | overflow: auto; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /modules/team/App/Doc/AppDocLayout.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/team/App/Doc/AppDocLayout.module.scss -------------------------------------------------------------------------------- /modules/team/App/Doc/Domain.tsx: -------------------------------------------------------------------------------- 1 | import { Doc } from '../../Domain/Doc'; 2 | import { DomainDetail } from '../../types'; 3 | import { AppDocLayout, AppDocLayoutProps } from './AppDocLayout'; 4 | 5 | export interface DomainDocProps extends AppDocLayoutProps { 6 | domain: DomainDetail; 7 | } 8 | 9 | export const DomainDoc = (props: DomainDocProps) => { 10 | return ( 11 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /modules/team/App/Doc/Scenario.tsx: -------------------------------------------------------------------------------- 1 | import { AppDocLayout, AppDocLayoutProps } from './AppDocLayout'; 2 | import { Doc, DocProps } from '../../Scenario/Doc'; 3 | 4 | export interface ScenarioDocProps extends AppDocLayoutProps, DocProps {} 5 | 6 | export const ScenarioDoc = (props: ScenarioDocProps) => { 7 | const { info, detail } = props; 8 | return ( 9 | 10 | 11 | 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /modules/team/App/Doc/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './AppDocLayout'; 2 | export * from './Doc'; 3 | export * from './Domain'; 4 | export * from './Scenario'; 5 | -------------------------------------------------------------------------------- /modules/team/Creator/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | font-size: 20px; 3 | color: var(--vd-color-gray-600); 4 | margin-top: var(--vd-spacing-xs); 5 | cursor: pointer; 6 | 7 | &:hover { 8 | color: var(--vd-color-gray-800); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/team/Domain/ApiDoc/TypeRender.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | } 3 | -------------------------------------------------------------------------------- /modules/team/Domain/ApiDoc/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /modules/team/Domain/Doc.module.scss: -------------------------------------------------------------------------------- 1 | .editor { 2 | position: relative; 3 | } 4 | -------------------------------------------------------------------------------- /modules/team/Domain/Reversion.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/team/Domain/Reversion.module.scss -------------------------------------------------------------------------------- /modules/team/README.md: -------------------------------------------------------------------------------- 1 | # 团队 2 | -------------------------------------------------------------------------------- /modules/team/Scenario/Reversion.module.scss: -------------------------------------------------------------------------------- 1 | .flowGraph { 2 | max-width: 50vw; 3 | max-height: 600px; 4 | } 5 | -------------------------------------------------------------------------------- /modules/team/Scenario/useStat.ts: -------------------------------------------------------------------------------- 1 | import type { ScenarioDSL } from '@/modules/scenario/api/dsl/interface'; 2 | import uniq from 'lodash/uniq'; 3 | import { useMemo } from 'react'; 4 | 5 | export function useStat(dsl?: ScenarioDSL) { 6 | return useMemo(() => { 7 | if (dsl == null) { 8 | return; 9 | } 10 | 11 | return { 12 | services: dsl.serviceModel.queries.length, 13 | domain: uniq(dsl.domainDependencies.filter(i => i.teamId == null && i.domainId).map(i => i.domainId)).length, 14 | team: uniq(dsl.domainDependencies.filter(i => i.teamId != null && i.domainId).map(i => i.teamId)).length, 15 | }; 16 | }, [dsl]); 17 | } 18 | -------------------------------------------------------------------------------- /modules/team/Team/index.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/team/Team/index.module.scss -------------------------------------------------------------------------------- /modules/team/TeamLayout/Context.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | import { TeamLayoutModel } from './TeamLayoutModel'; 3 | 4 | const CONTEXT = createContext(undefined); 5 | 6 | export const TeamLayoutProvider = CONTEXT.Provider; 7 | 8 | export function useTeamLayoutModel() { 9 | return useContext(CONTEXT); 10 | } 11 | -------------------------------------------------------------------------------- /modules/team/TeamLayout/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './TeamLayout'; 2 | export * from './TeamLayoutModel'; 3 | export { useTeamLayoutModel } from './Context'; 4 | -------------------------------------------------------------------------------- /modules/team/UbiquitousLanguage/README.md: -------------------------------------------------------------------------------- 1 | # 团队、组织统一语言 2 | -------------------------------------------------------------------------------- /modules/team/UbiquitousLanguage/TeamLanguage.tsx: -------------------------------------------------------------------------------- 1 | import { observer } from 'mobx-react'; 2 | import { useRouter } from 'next/router'; 3 | import { useLayoutTitle } from '@/modules/Layout'; 4 | 5 | import { LanguageScope } from './types'; 6 | import Language from './Language'; 7 | 8 | /** 9 | * 团队统一语言 10 | */ 11 | export const TeamLanguage = observer(function TeamLanguage() { 12 | const router = useRouter(); 13 | const teamId = router.query.id as string | undefined; 14 | 15 | useLayoutTitle('团队统一语言'); 16 | 17 | return ; 18 | }); 19 | 20 | export default TeamLanguage; 21 | -------------------------------------------------------------------------------- /modules/team/UbiquitousLanguage/types.ts: -------------------------------------------------------------------------------- 1 | import { UbiquitousLanguageItem } from '@/modules/domain/ubiquitous-language-design/types'; 2 | 3 | export interface LanguageItem extends UbiquitousLanguageItem { 4 | id: string; 5 | } 6 | 7 | export enum LanguageScope { 8 | ORGANIZATION_LANGUAGE = 1, 9 | TEAM_LANGUAGE = 2, 10 | DOMAIN_LANGUAGE = 3, 11 | } 12 | -------------------------------------------------------------------------------- /modules/user/AccountSetting/BaseInfo.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | textarea { 3 | resize: none; 4 | } 5 | } 6 | 7 | .avatar { 8 | display: flex; 9 | justify-content: center; 10 | padding: var(--vd-spacing-sm); 11 | } 12 | -------------------------------------------------------------------------------- /modules/user/AccountSetting/Invites.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | h3 { 3 | font-size: 14px; 4 | } 5 | 6 | .list { 7 | margin-top: 2em; 8 | } 9 | 10 | .table :global(.ant-pro-card-body) { 11 | padding: 0; 12 | } 13 | 14 | .input { 15 | width: 300px; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /modules/user/AccountSetting/ResetPassword.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/user/AccountSetting/ResetPassword.module.scss -------------------------------------------------------------------------------- /modules/user/AccountSetting/index.module.scss: -------------------------------------------------------------------------------- 1 | .root { 2 | --H: 70vh; 3 | :global(.ant-modal-header) { 4 | margin-bottom: 16px; 5 | } 6 | 7 | :global(.ant-modal-body) { 8 | height: var(--H); 9 | } 10 | 11 | :global(.ant-tabs-tab) { 12 | justify-content: flex-end; 13 | margin-top: 0; 14 | padding: 2px 16px !important; 15 | } 16 | } 17 | 18 | .tabs { 19 | height: 100%; 20 | :global(.ant-tabs-content) { 21 | height: calc(var(--H, 100%) * 0.95); 22 | overflow-x: hidden; 23 | overflow-y: auto; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /modules/user/Launch/TeamIcon.tsx: -------------------------------------------------------------------------------- 1 | export const TeamIcon = () => { 2 | return ( 3 | 4 | 8 | 9 | 10 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /modules/user/Launch/VerifyPermission.tsx: -------------------------------------------------------------------------------- 1 | import { useDeviceCheck } from '@/modules/session'; 2 | import { useVerifyPermission } from './useVerifyPermission'; 3 | 4 | /** 5 | * 验证访问权限 6 | * @returns 7 | */ 8 | export const VerifyPermission = () => { 9 | useVerifyPermission(); 10 | useDeviceCheck(); 11 | 12 | return null; 13 | }; 14 | 15 | export default VerifyPermission; 16 | -------------------------------------------------------------------------------- /modules/user/Launch/types.ts: -------------------------------------------------------------------------------- 1 | import type { TeamDetail } from '@/modules/organization/types'; 2 | import type { OrganizationDetail } from '@/modules/system/types'; 3 | 4 | export interface TeamDTOList { 5 | teamDTO: TeamDetail; 6 | isTeamAdmin: boolean; 7 | } 8 | 9 | export interface AccountOrganizationInfoList { 10 | organizationDTO: OrganizationDetail; 11 | isOrganizationAdmin: boolean; 12 | } 13 | 14 | export interface LaunchInfo { 15 | id: number; 16 | isSysAdmin: boolean; 17 | accountTeamInfoList: TeamDTOList[]; 18 | accountOrganizationInfoList: AccountOrganizationInfoList[]; 19 | } 20 | -------------------------------------------------------------------------------- /modules/user/Login/Login.module.scss: -------------------------------------------------------------------------------- 1 | .forgot { 2 | text-align: right; 3 | } 4 | -------------------------------------------------------------------------------- /modules/user/Login/Register.module.scss: -------------------------------------------------------------------------------- 1 | .register { 2 | :global(.ant-form-item-label > label) { 3 | height: 1em !important; 4 | } 5 | } 6 | 7 | .verify { 8 | display: flex; 9 | gap: var(--vd-spacing-sm); 10 | .codeInput { 11 | flex: 1; 12 | } 13 | } 14 | .codeBtn { 15 | width: 100px; 16 | } 17 | -------------------------------------------------------------------------------- /modules/user/Login/bg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/modules/user/Login/bg.jpeg -------------------------------------------------------------------------------- /modules/user/Login/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './Login'; 2 | export * from './Register'; 3 | export * from './Forgot'; 4 | export * from './ResetPassword'; 5 | -------------------------------------------------------------------------------- /modules/user/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-invite-code'; 2 | export * from './register'; 3 | -------------------------------------------------------------------------------- /pages/403.tsx: -------------------------------------------------------------------------------- 1 | export default function Forbidden() { 2 | return
你无权访问该页面
; 3 | } 4 | -------------------------------------------------------------------------------- /pages/404.tsx: -------------------------------------------------------------------------------- 1 | export { NotFound as default } from '@/modules/not-found'; 2 | -------------------------------------------------------------------------------- /pages/api/README.md: -------------------------------------------------------------------------------- 1 | # Node js 接口 2 | 3 | ## 目录结构定义 4 | 5 | - /rest: 标准的 restful 接口。如果是异常(非 2\*\*),会返回和 wakedata 接口一样的格式。 6 | - \*: 其他接口,使用 wakedata 接口规范,这些通常是一些业务接口。 7 | -------------------------------------------------------------------------------- /pages/api/create-invite-code.ts: -------------------------------------------------------------------------------- 1 | export { createInviteCode as default } from '@/modules/user/api'; 2 | -------------------------------------------------------------------------------- /pages/api/device-check.ts: -------------------------------------------------------------------------------- 1 | export { deviceCheck as default } from '@/modules/session/server'; 2 | -------------------------------------------------------------------------------- /pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /pages/api/login.ts: -------------------------------------------------------------------------------- 1 | import { login } from '@/modules/session/server'; 2 | 3 | export default login; 4 | -------------------------------------------------------------------------------- /pages/api/logout.ts: -------------------------------------------------------------------------------- 1 | import { logout } from '@/modules/session/server'; 2 | 3 | export default logout; 4 | -------------------------------------------------------------------------------- /pages/api/register.ts: -------------------------------------------------------------------------------- 1 | export { register as default } from '@/modules/user/api'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/ai/chat-supported.ts: -------------------------------------------------------------------------------- 1 | export { getChatSupported as default } from '@/modules/ai'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/ai/dall-e.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { dallE as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/data-object-builder.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { dataObjectBuilder as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/data-object.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { dataObject as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/ddd-master.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { dddMaster as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/echo.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { echo as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/extra-words.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | bodyParser: false, 5 | }, 6 | }; 7 | 8 | export { extraWords as default } from '@/modules/ai'; 9 | -------------------------------------------------------------------------------- /pages/api/rest/ai/fallback.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { fallback as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/flow-builder.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { flowBuilder as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/free-usage.ts: -------------------------------------------------------------------------------- 1 | export { freeUsage as default } from '@/modules/ai'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/ai/models.ts: -------------------------------------------------------------------------------- 1 | export { getModels as default } from '@/modules/ai'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/ai/proxy.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { chatGptProxy as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/sql-master.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { sqlMaster as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/subject.ts: -------------------------------------------------------------------------------- 1 | export { subject as default } from '@/modules/ai'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/ai/summary.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { summary as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/vision.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { vision as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/wakeadmin-form.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { wakeadminForm as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/wakeadmin-table.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | }, 5 | }; 6 | 7 | export { wakeadminTable as default } from '@/modules/ai'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/ai/words-to-ubiquitous-language.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | externalResolver: true, 4 | bodyParser: false, 5 | }, 6 | }; 7 | 8 | export { wordsToUbiquitousLanguage as default } from '@/modules/ai'; 9 | -------------------------------------------------------------------------------- /pages/api/rest/domain/[id]/base64.ts: -------------------------------------------------------------------------------- 1 | export { handleGetBase64 as default } from '@/modules/domain/api'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/domain/[id]/diff.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | bodyParser: false, 4 | }, 5 | }; 6 | 7 | export { handleGetDiff as default } from '@/modules/domain/api'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/domain/[id]/index.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next'; 2 | import { handleGet, handleSave } from '@/modules/domain/api'; 3 | 4 | export const config = { 5 | api: { 6 | bodyParser: false, 7 | }, 8 | }; 9 | 10 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 11 | switch (req.method) { 12 | case 'GET': 13 | await handleGet(req, res); 14 | break; 15 | case 'PUT': 16 | await handleSave(req, res); 17 | break; 18 | default: 19 | res.status(405).end('Method not allowed'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pages/api/rest/domain/[id]/v2.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next'; 2 | import { handleGet, handleSaveV2 } from '@/modules/domain/api'; 3 | 4 | export const config = { 5 | api: { 6 | bodyParser: false, 7 | }, 8 | }; 9 | 10 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 11 | switch (req.method) { 12 | case 'GET': 13 | await handleGet(req, res); 14 | break; 15 | case 'PUT': 16 | await handleSaveV2(req, res); 17 | break; 18 | default: 19 | res.status(405).end('Method not allowed'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pages/api/rest/domain/[id]/vector.ts: -------------------------------------------------------------------------------- 1 | export { handleGetVector as default } from '@/modules/domain/api'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/scenario/[id]/base64.ts: -------------------------------------------------------------------------------- 1 | export { handleGetBase64 as default } from '@/modules/scenario/api'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/scenario/[id]/diff.ts: -------------------------------------------------------------------------------- 1 | export const config = { 2 | api: { 3 | bodyParser: false, 4 | }, 5 | }; 6 | 7 | export { handleGetDiff as default } from '@/modules/scenario/api'; 8 | -------------------------------------------------------------------------------- /pages/api/rest/scenario/[id]/index.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next'; 2 | import { handleGet, handleSave } from '@/modules/scenario/api'; 3 | 4 | export const config = { 5 | api: { 6 | bodyParser: false, 7 | }, 8 | }; 9 | 10 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 11 | switch (req.method) { 12 | case 'GET': 13 | await handleGet(req, res); 14 | break; 15 | case 'PUT': 16 | await handleSave(req, res); 17 | break; 18 | default: 19 | res.status(405).end('Method not allowed'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pages/api/rest/scenario/[id]/v2.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next'; 2 | import { handleGet, handleSaveV2 } from '@/modules/scenario/api'; 3 | 4 | export const config = { 5 | api: { 6 | bodyParser: false, 7 | }, 8 | }; 9 | 10 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 11 | switch (req.method) { 12 | case 'GET': 13 | await handleGet(req, res); 14 | break; 15 | case 'PUT': 16 | await handleSaveV2(req, res); 17 | break; 18 | default: 19 | res.status(405).end('Method not allowed'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pages/api/rest/scenario/[id]/vector.ts: -------------------------------------------------------------------------------- 1 | export { handleGetVector as default } from '@/modules/scenario/api'; 2 | -------------------------------------------------------------------------------- /pages/api/rest/session.ts: -------------------------------------------------------------------------------- 1 | import { session } from '@/modules/session/server'; 2 | 3 | /** 4 | * SESSION 格式 5 | */ 6 | export default session; 7 | -------------------------------------------------------------------------------- /pages/api/session.ts: -------------------------------------------------------------------------------- 1 | import { session } from '@/modules/session/server'; 2 | 3 | export default session; 4 | -------------------------------------------------------------------------------- /pages/api/update-entry.ts: -------------------------------------------------------------------------------- 1 | import { updateEntry } from '@/modules/session/server'; 2 | 3 | export default updateEntry; 4 | -------------------------------------------------------------------------------- /pages/forgot.tsx: -------------------------------------------------------------------------------- 1 | export { Forgot as default } from '@/modules/user/Login'; 2 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { Home } from '@/modules/home'; 2 | 3 | export default function Page() { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /pages/login.ts: -------------------------------------------------------------------------------- 1 | export { Login as default } from '@/modules/user/Login'; 2 | -------------------------------------------------------------------------------- /pages/organization/[id].tsx: -------------------------------------------------------------------------------- 1 | import { getOrganizationLayout } from '@/modules/organization/OrganizationLayout'; 2 | import dynamic from 'next/dynamic'; 3 | 4 | const Organization = dynamic(() => import('@/modules/organization/Organization'), { ssr: false }); 5 | 6 | /** 7 | * 组织管理 8 | * @returns 9 | */ 10 | export default function OrganizationPage() { 11 | return ; 12 | } 13 | 14 | OrganizationPage.getLayout = getOrganizationLayout; 15 | -------------------------------------------------------------------------------- /pages/register.tsx: -------------------------------------------------------------------------------- 1 | export { Register as default } from '@/modules/user/Login'; 2 | import { GetServerSideProps } from 'next'; 3 | 4 | export const getServerSideProps: GetServerSideProps<{ 5 | warning?: string; 6 | }> = async context => { 7 | const { i } = context.query; 8 | if (process.env.REQUIRE_INVITATION === 'true' && i == null) { 9 | return { 10 | props: { 11 | warning: '目前仅支持邀请注册', 12 | }, 13 | }; 14 | } 15 | 16 | return { 17 | props: {}, 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /pages/reset-password.tsx: -------------------------------------------------------------------------------- 1 | export { ResetPassword as default } from '@/modules/user/Login'; 2 | -------------------------------------------------------------------------------- /pages/sentry_sample_server_error.tsx: -------------------------------------------------------------------------------- 1 | import { GetServerSideProps } from 'next'; 2 | 3 | export default function SentrySampleServerError() { 4 | return
just for test
; 5 | } 6 | 7 | export const getServerSideProps: GetServerSideProps = async () => { 8 | throw new Error('test server side error'); 9 | }; 10 | -------------------------------------------------------------------------------- /pages/system/index.tsx: -------------------------------------------------------------------------------- 1 | import { GetServerSideProps } from 'next'; 2 | 3 | export default function SystemIndex() { 4 | return null; 5 | } 6 | 7 | export const getServerSideProps: GetServerSideProps = async () => { 8 | return { 9 | redirect: { 10 | permanent: false, 11 | destination: '/system/organization', 12 | }, 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /pages/system/organization/index.tsx: -------------------------------------------------------------------------------- 1 | import dynamic from 'next/dynamic'; 2 | import { getSystemLayout } from '@/modules/system/SystemLayout'; 3 | 4 | const Organization = dynamic(() => import('@/modules/system/Organization'), { ssr: false }); 5 | 6 | /** 7 | * 组织管理 8 | * @returns 9 | */ 10 | export default function OrganizationPage() { 11 | return ; 12 | } 13 | 14 | OrganizationPage.getLayout = getSystemLayout; 15 | -------------------------------------------------------------------------------- /pages/system/user/index.tsx: -------------------------------------------------------------------------------- 1 | import dynamic from 'next/dynamic'; 2 | import { getSystemLayout } from '@/modules/system/SystemLayout'; 3 | 4 | const User = dynamic(() => import('@/modules/system/User'), { ssr: false }); 5 | 6 | /** 7 | * 用户管理 8 | * @returns 9 | */ 10 | export default function UserPage() { 11 | return ; 12 | } 13 | 14 | UserPage.getLayout = getSystemLayout; 15 | -------------------------------------------------------------------------------- /pages/team/[id]/app/index.tsx: -------------------------------------------------------------------------------- 1 | import { getTeamLayout } from '@/modules/team/TeamLayout'; 2 | import dynamic from 'next/dynamic'; 3 | 4 | const Home = dynamic(() => import('@/modules/team/App/Home'), { ssr: false }); 5 | 6 | /** 7 | * 应用首页 8 | * @returns 9 | */ 10 | export default function App() { 11 | return ; 12 | } 13 | 14 | App.getLayout = getTeamLayout; 15 | -------------------------------------------------------------------------------- /pages/team/[id]/domain/index.tsx: -------------------------------------------------------------------------------- 1 | import { getTeamLayout } from '@/modules/team/TeamLayout'; 2 | import dynamic from 'next/dynamic'; 3 | 4 | const DomainHome = dynamic(() => import('@/modules/team/Domain/Home'), { ssr: false }); 5 | 6 | /** 7 | * 业务域首页 8 | * @returns 9 | */ 10 | export default function Domain() { 11 | return ; 12 | } 13 | 14 | Domain.getLayout = getTeamLayout; 15 | -------------------------------------------------------------------------------- /pages/team/[id]/scenario/index.tsx: -------------------------------------------------------------------------------- 1 | import { getTeamLayout } from '@/modules/team/TeamLayout'; 2 | import dynamic from 'next/dynamic'; 3 | 4 | const ScenarioHome = dynamic(() => import('@/modules/team/Scenario/Home'), { ssr: false }); 5 | 6 | /** 7 | * 业务场景首页 8 | * @returns 9 | */ 10 | export default function Scenario() { 11 | return ; 12 | } 13 | 14 | Scenario.getLayout = getTeamLayout; 15 | -------------------------------------------------------------------------------- /pages/team/[id]/ubiquitous-language/index.tsx: -------------------------------------------------------------------------------- 1 | import { getTeamLayout } from '@/modules/team/TeamLayout'; 2 | import dynamic from 'next/dynamic'; 3 | 4 | const TeamLanguage = dynamic(() => import('@/modules/team/UbiquitousLanguage/TeamLanguage'), { ssr: false }); 5 | 6 | /** 7 | * 团队首页 8 | * @returns 9 | */ 10 | export default function UbiquitousLanguage() { 11 | return ; 12 | } 13 | 14 | UbiquitousLanguage.getLayout = getTeamLayout; 15 | -------------------------------------------------------------------------------- /pages/team/[id]/ubiquitous-language/organization.tsx: -------------------------------------------------------------------------------- 1 | import { getTeamLayout } from '@/modules/team/TeamLayout'; 2 | import dynamic from 'next/dynamic'; 3 | 4 | const OrganizationLanguage = dynamic(() => import('@/modules/team/UbiquitousLanguage/OrganizationLanguage'), { 5 | ssr: false, 6 | }); 7 | 8 | /** 9 | * 组织统一语言 10 | * @returns 11 | */ 12 | export default function UbiquitousLanguage() { 13 | return ; 14 | } 15 | 16 | UbiquitousLanguage.getLayout = getTeamLayout; 17 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | 'postcss-flexbugs-fixes': {}, 5 | 'postcss-preset-env': { 6 | autoprefixer: { 7 | flexbox: 'no-2009', 8 | }, 9 | stage: 3, 10 | features: { 11 | 'custom-properties': false, 12 | }, 13 | }, 14 | 'postcss-increase-specificity': { 15 | repeat: 1, 16 | }, 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /public/excel-templates/ubiquitous-language.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/public/excel-templates/ubiquitous-language.xlsx -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/public/favicon.ico -------------------------------------------------------------------------------- /public/monaco/min/vs/base/browser/ui/codicons/codicon/codicon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/visual-ddd/visual-ddd-client/de3b849884f4ac135c4607f784868f339e214a02/public/monaco/min/vs/base/browser/ui/codicons/codicon/codicon.ttf -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.de.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.de",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.de.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.es.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.es",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.es.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.fr.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.fr",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.fr.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.it.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.it",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.it.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.ja.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.ja",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.ja.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.ko.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.ko",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.ko.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.ru.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.ru",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.ru.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.zh-cn.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.zh-cn",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.zh-cn.js.map -------------------------------------------------------------------------------- /public/monaco/min/vs/base/common/worker/simpleWorker.nls.zh-tw.js: -------------------------------------------------------------------------------- 1 | /*!----------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Version: 0.37.1(20a8d5a651d057aaed7875ad1c1f2ecf13c4e773) 4 | * Released under the MIT license 5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt 6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.zh-tw",{"vs/base/common/platform":["_"]}); 7 | 8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.zh-tw.js.map -------------------------------------------------------------------------------- /scripts/build-docker-free.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | # 容器构建 7 | # 需要提供以下参数 8 | 9 | # DOCKER_USER docker 用户 10 | # DOCKER_PASSWORD docker 用户密码 11 | 12 | env 13 | node -v 14 | 15 | cd ./scripts && npm i && cd - 16 | 17 | # 构建镜像 18 | node ./scripts/docker-build.js 19 | 20 | # 发布 21 | node ./scripts/docker-publish.js 22 | -------------------------------------------------------------------------------- /scripts/build-in-zadig.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Zadig 中构建 4 | # 和Jenkins 的区别 5 | # zadig 接管了 docker 的构建和发布,不需要登录,直接使用 $IMAGE 构建即可 6 | # 默认不在项目目录下,需要手动切换 7 | 8 | set -e 9 | set -x 10 | 11 | # 不进行登录 12 | export DOCKER_SKIP_LOGIN=true 13 | 14 | # 切换到项目目录 15 | cd $WORKSPACE/$REPONAME_0 16 | 17 | env 18 | node -v 19 | 20 | cd ./scripts && npm i && cd - 21 | 22 | # 构建镜像 23 | node ./scripts/docker-build-in-zadig.js 24 | 25 | docker push $IMAGE 26 | -------------------------------------------------------------------------------- /scripts/build-publish-collab-server.js: -------------------------------------------------------------------------------- 1 | const { build, publish } = require('@wakeadmin/docker-build'); 2 | const { DOCKER_IMAGE_PREFIX, PKG_VERSION } = require('./shared'); 3 | 4 | const imageName = `${DOCKER_IMAGE_PREFIX}/collab-server`; 5 | 6 | if (process.cwd().endsWith('collab-server')) { 7 | build(imageName, {}, '--progress plain'); 8 | publish(imageName, PKG_VERSION, true); 9 | } else { 10 | console.log(`构建 ${imageName} 失败 -> 路径不正确(${process.cwd()})`); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/build-publish-signaling.js: -------------------------------------------------------------------------------- 1 | const { build, publish } = require('@wakeadmin/docker-build'); 2 | const { DOCKER_IMAGE_PREFIX, PKG_VERSION } = require('./shared'); 3 | 4 | const imageName = `${DOCKER_IMAGE_PREFIX}/signaling`; 5 | 6 | if (process.cwd().endsWith('signaling')) { 7 | build(imageName, {}, '--progress plain'); 8 | publish(imageName, PKG_VERSION, true); 9 | } else { 10 | console.log(`构建 ${imageName} 失败 -> 路径不正确(${process.cwd()})`); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | # 容器构建 7 | # 需要提供以下参数 8 | 9 | # DOCKER_USER docker 用户 10 | # DOCKER_PASSWORD docker 用户密码 11 | 12 | env 13 | node -v 14 | 15 | cd ./scripts && npm i && cd - 16 | 17 | # 构建镜像 18 | node ./scripts/docker-build.js 19 | 20 | # 发布 21 | node ./scripts/docker-publish.js 22 | 23 | cd ./collab-server 24 | node ../scripts/build-publish-collab-server.js 25 | cd - 26 | 27 | cd ./signaling 28 | node ../scripts/build-publish-signaling.js 29 | cd - 30 | -------------------------------------------------------------------------------- /scripts/docker-build-in-zadig.js: -------------------------------------------------------------------------------- 1 | const { build } = require('@wakeadmin/docker-build'); 2 | 3 | build( 4 | process.env.IMAGE, 5 | { 6 | SENTRY_DSN: process.env.SENTRY_DSN, 7 | SENTRY_AUTH_TOKEN: process.env.SENTRY_AUTH_TOKEN, 8 | SENTRY_ORG: process.env.SENTRY_ORG, 9 | SENTRY_PROJECT: process.env.SENTRY_PROJECT, 10 | PRODUCTION_SOURCE_MAP: process.env.PRODUCTION_SOURCE_MAP, 11 | }, 12 | '--progress plain' 13 | ); 14 | -------------------------------------------------------------------------------- /scripts/docker-build.js: -------------------------------------------------------------------------------- 1 | const { build } = require('@wakeadmin/docker-build'); 2 | const { DOCKER_IMAGE_NAME } = require('./shared'); 3 | 4 | build( 5 | DOCKER_IMAGE_NAME, 6 | { 7 | SENTRY_DSN: process.env.SENTRY_DSN, 8 | SENTRY_AUTH_TOKEN: process.env.SENTRY_AUTH_TOKEN, 9 | SENTRY_ORG: process.env.SENTRY_ORG, 10 | SENTRY_PROJECT: process.env.SENTRY_PROJECT, 11 | PRODUCTION_SOURCE_MAP: process.env.PRODUCTION_SOURCE_MAP, 12 | BD_ANALYZE_KEY: process.env.BD_ANALYZE_KEY, 13 | }, 14 | '--progress plain' 15 | ); 16 | -------------------------------------------------------------------------------- /scripts/docker-publish.js: -------------------------------------------------------------------------------- 1 | const { publish, clean } = require('@wakeadmin/docker-build'); 2 | const { DOCKER_IMAGE_NAME, DOCKER_VERSION, DOCKER_PUBLISH_LATEST } = require('./shared'); 3 | 4 | // 发布需要提供 DOCKER_USER、DOCKER_PASSWORD、DOCKER_SERVER, DOCKER_PUBLISH_LATEST 等环境变量 5 | 6 | publish(DOCKER_IMAGE_NAME, DOCKER_VERSION, DOCKER_PUBLISH_LATEST); 7 | 8 | // 保留缓存 9 | // clean(DOCKER_IMAGE_NAME); 10 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scripts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "docker-build-in-zadig.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@wakeadmin/docker-build": "^0.1.9" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /signaling/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /signaling/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:19-alpine3.16 2 | 3 | WORKDIR /app 4 | ENV NODE_ENV production 5 | ENV PORT 8080 6 | EXPOSE 8080 7 | 8 | COPY ./package.json ./ 9 | 10 | RUN npm install 11 | 12 | CMD ["node", "./node_modules/y-webrtc/bin/server.js"] 13 | -------------------------------------------------------------------------------- /signaling/README.md: -------------------------------------------------------------------------------- 1 | # yjs WebRTC 信令服务器 2 | 3 | **deprecated!!!** 4 | 5 | # Build 6 | 7 | ```shell 8 | $ docker build -t wkfe/visual-ddd-signaling --platform linux/amd64 . 9 | 10 | # 打版本 11 | $ docker tag wkfe/visual-ddd-signaling 作用域/wkfe/visual-ddd:版本号或latest 12 | 13 | # 推送 14 | $ docker push 作用域/wkfe/visual-ddd:版本号或latest 15 | ``` 16 | 17 | # Run 18 | 19 | 暴露 8080 端口 20 | -------------------------------------------------------------------------------- /signaling/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "signaling", 3 | "version": "1.0.0", 4 | "description": "yjs WebRTC 信令服务器, 已废弃,使用 Hocuspocus 形式", 5 | "deprecated": true, 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "y-webrtc": "^10.2.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /styles/override.css: -------------------------------------------------------------------------------- 1 | .ant-form-item-explain { 2 | font-size: var(--vd-font-size-h6) !important; 3 | } 4 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | --------------------------------------------------------------------------------