Compare commits

...

7 Commits

Author SHA1 Message Date
OpenTiny f629a5e6d4 原子化重构框架搭建
Match-id-b776ab82a6cb2da3c6af12ee6db97ea612b0dd93
2024-05-21 16:25:18 +08:00
OpenTiny 0ccd5c050c feat: 添加区块构建代码
Match-id-3848a3dcf0de114905b43261099894c9f3a83f51
2023-12-14 17:18:52 +08:00
OpenTiny 9b7bf4eb09 feat: 同步外部代码到out分支
Match-id-d527f2f763b5c3cadc34d8fe46b7781afb38e3a9
2023-12-14 17:14:20 +08:00
OpenTiny 88509ee8db refactor: 支持 pnpm
Match-id-d6d5411f705f8d59f001f96ad3d043a8164839c0
2023-09-28 18:18:57 +08:00
OpenTiny 552782671e update readme (#6)
* fix: add logo and fix readme

* fix: update readme

Match-id-2d1dc77d489c5d0651d4b26ddae718019716cd48
2023-09-28 17:39:50 +08:00
OpenTiny cc35c5f673 fix: add logo and fix readme (#5)
Match-id-03efb7c8a1b05fa9b99ac88a6a82ea2ae5236bfb
2023-09-28 17:39:32 +08:00
OpenTiny 418b96687a fix: fix build error (#1)
* fix: fix build error

* fix: fix server dependence

Match-id-22cc76beb68e512f012e9fa4219458bd548b4c81
2023-09-28 17:39:10 +08:00
1618 changed files with 43177 additions and 22853 deletions

View File

@ -8,4 +8,4 @@ tool_params:
secsolar:
source_dir: ./
cmetrics:
exclude: vite.config.js|package.json|index.js|mockServer/assets
exclude: vite.config.js|package.json|index.js|mockServer/assets|packages/vue-generator/test

View File

@ -1,4 +0,0 @@
# alpha mode, used by the "build:alpha" script
NODE_ENV=production
#VITE_ORIGIN=

View File

@ -1,5 +0,0 @@
# development mode, used by the "vite" command
NODE_ENV=development
# request data via alpha service
#VITE_ORIGIN=

View File

@ -1,4 +0,0 @@
# prod mode, used by the "build:prod" script
NODE_ENV=production
#VITE_ORIGIN=

View File

@ -5,3 +5,5 @@ package-lock.json
**/node_modules/**
tmp
temp
mockServer
packages/vue-generator/**/output/**

81
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@ -0,0 +1,81 @@
name: '🐛 Bug report'
description: Create a report to help us improve Tiny Engine
title: '🐛 [Bug]: '
labels: ['🐛 bug']
body:
- type: markdown
attributes:
value: |
Please fill out the following carefully in order to better fix the problem.
- type: input
id: Environment
attributes:
label: Environment
description: |
**Depending on your browser and operating system, websites may behave differently from one environment to another. Make sure your developers know your technical environment.**
placeholder: Please browser information.
validations:
required: true
- type: input
id: node-version
attributes:
label: Version
description: |
### **Check if the issue is reproducible with the latest stable version.**
You can use the command `node -v` to view it
placeholder: latest
validations:
required: true
- type: input
id: tiny-vue-version
attributes:
label: Version
description: |
### **Check if the issue is reproducible with the latest stable version.**
You can use the command `npm ls @opentiny/vue` to view it
placeholder: latest
validations:
required: true
- type: textarea
id: minimal-repo
attributes:
label: Link to minimal reproduction
description: |
**Provide a streamlined CodePen / CodeSandbox or GitHub repository link as much as possible. Please don't fill in a link randomly, it will only close your issue directly.**
placeholder: Please Input
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Step to reproduce
description: |
**After the replay is turned on, what actions do we need to perform to make the bug appear? Simple and clear steps can help us locate the problem more quickly. Please clearly describe the steps of reproducing the issue. Issues without clear reproducing steps will not be repaired. If the issue marked with 'need reproduction' does not provide relevant steps within 7 days, it will be closed directly.**
placeholder: Please Input
validations:
required: true
- type: textarea
id: expected
attributes:
label: What is expected
placeholder: Please Input
- type: textarea
id: actually
attributes:
label: What is actually happening
placeholder: Please Input
- type: input
id: project-name
attributes:
label: What is your project name
description: We also welcome you to fill in more detailed project information in the following issue [#334](https://github.com/opentiny/tiny-engine/issues/334).
placeholder: Please Input
validations:
required: true
- type: textarea
id: additional-comments
attributes:
label: Any additional comments (optional)
description: |
**Some background / context of how you ran into this bug.**
placeholder: Please Input

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Questions or need help
url: https://github.com/opentiny/tiny-engine/discussions
about: Add this WeChat(opentiny-official), we will invite you to the WeChat discussion group later.

View File

@ -0,0 +1,31 @@
name: ✨ Feature Request
description: Propose new features to @opentiny/tiny-engine to improve it.
title: '✨ [Feature]: '
labels: ['✨ feature']
body:
- type: textarea
id: feature-solve
attributes:
label: What problem does this feature solve
description: |
Explain your use case, context, and rationale behind this feature request. More importantly, what is the end user experience you are trying to build that led to the need for this feature?
placeholder: Please Input
validations:
required: true
- type: textarea
id: feature-api
attributes:
label: What does the proposed API look like
description: |
Describe how you propose to solve the problem and provide code samples of how the API would work once implemented. Note that you can use Markdown to format your code blocks.
placeholder: Please Input
validations:
required: true
- type: input
id: project-name
attributes:
label: What is your project name
description: We also welcome you to fill in more detailed project information in the following issue [#334](https://github.com/opentiny/tiny-engine/issues/334).
placeholder: Please Input
validations:
required: true

52
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,52 @@
English | [简体中文](https://github.com/opentiny/tiny-engine/blob/develop/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.zh-CN.md)
# PR
## PR Checklist
Please check if your PR fulfills the following requirements:
- [ ] The commit message follows our [Commit Message Guidelines](https://github.com/opentiny/tiny-engine/blob/develop/CONTRIBUTING.md)
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
- [ ] Built its own designer, fully self-validated
## PR Type
What kind of change does this PR introduce?
<!-- Please check the one that applies to this PR using "x". -->
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] Other... Please describe:
## Background and solution
<!--
1. Describe the problem and the scenario.
2. New features need to be described and attached with renderings.
3. Screenshots or GIFs involving UI/Interaction changes/Bugfix before and after modification are required.
-->
### What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
Issue Number: N/A
### What is the new behavior?
## Does this PR introduce a breaking change?
- [ ] Yes
- [ ] No
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
## Other information

View File

@ -0,0 +1,52 @@
[English](https://github.com/opentiny/tiny-engine/blob/develop/.github/PULL_REQUEST_TEMPLATE.md) | 简体中文
# PR
## PR Checklist
请检查您的 PR 是否满足以下要求:
- [ ] commit message遵循我们的[提交贡献指南](https://github.com/opentiny/tiny-engine/blob/develop/CONTRIBUTING.md)
- [ ] 添加了更改内容的测试用例用于bugfix/功能)
- [ ] 文档已添加/更新用于bugfix/功能)
- [ ] 是否构建了自己的设计器,经过了充分的自验证
## PR 类型
这个PR的类型是
- [ ] 日常 bug 修复
- [ ] 新特性支持
- [ ] 代码风格优化
- [ ] 重构
- [ ] 构建优化
- [ ] 测试用例
- [ ] 文档更新
- [ ] 分支合并
- [ ] 其他改动(请补充)
## 需求背景和解决方案
<!--
1. 要解决的具体问题。
2. 新增特性,需要进行功能描述,并附上效果图。
3. 涉及UI/交互变动/Bugfix需要有修改前&修改后截图或 GIF。
-->
Issue Number: N/A
### 修改前
### 修改后
## 此PR是否含有 breaking change?
- [ ] 是
- [ ] 否
<!-- 如果此 PR 包含breaking change请在下面从用户角度描述具体变化和其他风险。-->
## Other information

26
.github/release.yml vendored Normal file
View File

@ -0,0 +1,26 @@
changelog:
exclude:
labels:
- ignore-for-release
authors:
- allcontributors[bot]
categories:
- title: Breaking Changes 🛠
labels:
- Semver-Major
- breaking-change
- title: Exciting New Features 🎉
labels:
- Semver-Minor
- feature
- enhancement
- title: Bug Fixes 🐛
labels:
- Semver-Patch
- bug
- title: Other Changes
labels:
- documentation
- refactoring
- unit-test
- ci

18
.github/workflows/issue-translator.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: 'issue-translator'
on:
issue_comment:
types: [created]
issues:
types: [opened]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: usthe/issues-translate-action@v2.7
with:
IS_MODIFY_TITLE: false
# 非必须决定是否需要修改issue标题内容
# 若是true则机器人账户@Issues-translate-bot必须拥有修改此仓库issue权限。可以通过邀请@Issues-translate-bot加入仓库协作者实现。
CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically.
# 非必须,自定义机器人翻译的前缀开始内容。

36
.github/workflows/push-check.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Push And Create PR Check
on:
push:
branches: []
pull_request:
branches: [develop,main]
jobs:
push-check:
runs-on: ubuntu-latest # windows-latest || macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Install pnpm
run: npm i -g pnpm
- name: Install dependencies
run: pnpm i
- name: Get changed files
id: get_changed_files
uses: tj-actions/changed-files@v41
with:
files: |
**.js
**.vue
**.jsx
- name: Run ESLint
run: npx eslint ${{steps.get_changed_files.outputs.all_changed_files}}
- name: Run Build
run: pnpm run build:plugin && pnpm run build:alpha

3
.gitignore vendored
View File

@ -3,6 +3,9 @@ node_modules
dist/
package-lock.json
yarn.lock
pnpm-lock.yaml
lerna-debug.log
packages/design-core/bundle-deps
# local env files
.env.local

View File

@ -2,5 +2,5 @@
. "$(dirname -- "$0")/_/husky.sh"
# npm run lint
npx lint-staged
npx lint-staged -q

View File

@ -18,7 +18,6 @@ package-lock.json
# 忽略可能存在的其它编辑器文件夹
.idea
/src/app/public/mock/*
!/src/app/public/mock/graph-bundle.json
tmp
temp
/packages/design-core/public/mock/*
**/**/tmp
**/**/temp

View File

@ -51,14 +51,11 @@ Local startup steps:
git clone git@github.com:username/tiny-engine.git
cd tiny-engine
git remote add upstream git@github.com:opentiny/tiny-engine.git
npm i
pnpm i
# Start the project.
$ npm run serve
$ pnpm dev
# start another terminal
$ cd mockServer
$ npm run dev
```
To submit a PR:
@ -67,7 +64,7 @@ To submit a PR:
- Local coding.
- Submit according to [Commit Message Format](https://www.conventionalcommits.org/zh-hans/v1.0.0/) specification. PR that do not conform to the submission specification will not be merged.
- Submit to remote repository: `git push origin branchName`.
- (Optional) Synchronize upstream repository dev branch latest code: `git pull upstream dev`.
- (Optional) Synchronize upstream repository dev branch latest code: `git pull upstream develop`.
- Open the [Pull requests](https://github.com/opentiny/tiny-engine/pulls) link of the TinyEngine code repository and click the New pull request button to submit the PR.
- Project Committer conducts Code Review and makes comments.
- The PR author adjusts the code according to the opinion. Please note that when a branch initiates PR, the subsequent commit will be synchronized automatically, and there is no need to resubmit the PR.

View File

@ -42,23 +42,18 @@
- 点击 [TinyEngine](https://github.com/opentiny/tiny-engine) 代码仓库右上角的 Fork 按钮,将上游仓库 Fork 到个人仓库
- Clone 个人仓库到本地
- 在 TinyEngine 根目录下运行 `npm install`, 安装依赖
- 在 TinyEngine mockServer 运行 `npm install`, 安装依赖
- 在 TinyEngine 根目录下运行 `npm run serve`,再到 mockServer 目录下运行 `npm run dev`,启动本地开发
- 在 TinyEngine 根目录下运行 `pnpm i`, 安装依赖
- 在 TinyEngine 根目录下运行 `pnpm dev`,启动本地开发
```shell
# username 为用户名,执行前请替换
git clone git@github.com:username/tiny-engine.git
cd tiny-engine
git remote add upstream git@github.com:opentiny/tiny-engine.git
npm i
pnpm i
# 启动项目
$ npm run serve
# start another terminal
$ cd mockServer
$ npm run dev
$ pnpm dev
```
@ -68,7 +63,7 @@ $ npm run dev
- 本地编码
- 遵循 Commit Message Format 规范进行提交,不符合提交规范的 PR 将不会被合并
- 提交到远程仓库git push origin branchName
- (可选)同步上游仓库 dev 分支最新代码git pull upstream dev
- (可选)同步上游仓库 develop 分支最新代码git pull upstream develop
- 打开 TinyEngine 代码仓库的 [Pull requests](https://github.com/opentiny/tiny-engine/pulls) 链接,点击 New pull request 按钮提交 PR
- 项目 Committer 进行 Code Review并提出意见
- PR 作者根据意见调整代码,请注意一个分支发起了 PR 后,后续的 commit 会自动同步,无需重新提交 PR

View File

@ -1,102 +0,0 @@
<p align="center">
<a href="https://opentiny.design/tiny-engine" target="_blank" rel="noopener noreferrer">
<img alt="OpenTiny Logo" src="logo.svg" height="100" style="max-width:100%;">
</a>
</p>
<p align="center">TinyEngine enables developers to customize low-code platforms, build low-bit platforms online in real time, and support secondary development or integration of low-bit platform capabilities.</p>
English | [简体中文](README.zh-CN.md)
🌈 Features:
- Cross-end cross-frame front-end components
- Supports online real-time construction, secondary development, or being integrated.
- Directly generate deployable source code without engine support.
- Allows access to third-party components and customized extension plug-ins.
- Supports high-code and low-code, and hybrid development and deployment of applications.
- The platform accesses AI big model capabilities to help developers build applications.
## Development
### Dependencies required for installation
```sh
$ npm install
$ pushd mockServer
$ npm install
$ popd
```
### Local development: Start the local mock server and use the mock data of the local mock server.
```sh
$ npm run serve
# start another terminal
$ cd mockServer
$ npm run dev
```
Open a browser: `http://localhost:8080/?type=app&id=918&tenant=1&pageid=NTJ4MjvqoVj8OVsc`
`url search` Parameters:
- `type=app` Application type
- `id=xxx` Application ID
- `tenant=xxx` Organization ID
- `pagdId=xxx` Page ID
## Build
```sh
# Build all plug-ins first
npm run build:plugin
# Build Designer
npm run build:alpha or build:prod
# Release all plug-ins.
npm run publish:plugin
# Publish the designer.
npm run publish:core
```
## Common Packet Sending Process
1. Release the plug-in.
```sh
npm run build:plugin && npm run publish:plugin
```
2. Publish Designer
a) Change the package name and version number.
Package name: @opentiny/tinybuilder-design-core-test
Version number: The last digit plus 1 each time. For example:
```
"name": "@opentiny/tinybuilder-design-core-test",
"version": "1.0.87",
```
b) npm publish
## 🤝 Participation and Contribution
If you are interested in our open source project, please join us! 🎉
Please read the [Contribution Guide](CONTRIBUTING.md) before participating in the contribution.
- Add official assistant WeChat opentiny-official and join the technical exchange group
- Join the mailing list opentiny@googlegroups.com
## Open source protocol
[MIT](LICENSE)
```
```

View File

@ -17,25 +17,45 @@ English | [简体中文](README.zh-CN.md)
- Supports high-code and low-code, and hybrid development and deployment of applications.
- The platform accesses AI big model capabilities to help developers build applications.
## Documentation
- introhttps://opentiny.design/tiny-engine#/home
- tutorialhttps://opentiny.design/tiny-engine#/help-center/course/engine
- playgroundhttps://opentiny.design/tiny-engine#/tiny-engine-editor
## Development
### Dependencies required for installation
```sh
$ npm install
$ pushd mockServer
$ npm install
$ popd
$ pnpm install
```
### Local development: Start the local mock server and use the mock data of the local mock server.
```sh
$ npm run serve
$ pnpm dev
```
# start another terminal
$ cd mockServer
$ npm run dev
## Local development, directly connected to the local tiny-engine-webservice server
1. Start <a href="https://github.com/opentiny/tiny-engine-data-center/blob/main/README.md" target="_blank">tiny-engine-data-center</a>
2. Start <a href="https://github.com/opentiny/tiny-engine-webservice/blob/main/README.md" target="_blank">tiny-engine-webservice</a>
3. Modify the origin value in `vite.config.js` in the `packages/design-core/` directory of the tiny-engine project to be the address port of your local webService project (the webService port defaults to 7011), such as:
<img alt="Modify port" src="https://res.hc-cdn.com/lowcode-portal/1.1.55/img/docimg/backend_deploy_5.png">
### Materials Synchronization [Solution](https://opentiny.design/tiny-engine#/help-center/course/engine/56)
```sh
$ pnpm splitMaterials
```
```sh
$ pnpm buildMaterials
```
Open a browser: `http://localhost:8080/?type=app&id=918&tenant=1&pageid=NTJ4MjvqoVj8OVsc`
@ -44,45 +64,35 @@ Open a browser: `http://localhost:8080/?type=app&id=918&tenant=1&pageid=NTJ4Mjvq
- `type=app` Application type
- `id=xxx` Application ID
- `tenant=xxx` Organization ID
- `pagdId=xxx` Page ID
- `pageid=xxx` Page ID
## Build
```sh
# Build all plug-ins first
npm run build:plugin
pnpm build:plugin
# Build Designer
npm run build:alpha or build:prod
# Release all plug-ins.
npm run publish:plugin
# Publish the designer.
npm run publish:core
pnpm build:alpha or build:prod
```
## Common Packet Sending Process
1. Release the plug-in.
```sh
npm run build:plugin && npm run publish:plugin
The folder where the product is located after building
```
tiny-engine/packages/design-core/dist/
```
2. Publish Designer
## Milestones
a) Change the package name and version number.
Package name: @opentiny/tinybuilder-design-core-test
Version number: The last digit plus 1 each time. For example:
```mermaid
gantt
dateFormat YYYY-MM-DD
axisFormat %Y-%m-%d
1.0.0-beta.x version :active,2023-09-25, 2024-03-31
1.0.0-rc version : 2024-04-01, 2024-06-30
1.0.0 version : 2024-07-01, 2024-07-31
```
"name": "@opentiny/tinybuilder-design-core-test",
"version": "1.0.87",
```
b) npm publish
## 🤝 Participation and Contribution
@ -93,6 +103,6 @@ Please read the [Contribution Guide](CONTRIBUTING.md) before participating in th
- Add official assistant WeChat opentiny-official and join the technical exchange group
- Join the mailing list opentiny@googlegroups.com
## Open source protocol
## License
[MIT](LICENSE)

View File

@ -17,26 +17,45 @@
- 支持高代码与低代码,混合开发部署应用
- 平台接入 AI 大模型能力,辅助开发者构建应用
## 文档
- 介绍https://opentiny.design/tiny-engine#/home
- 使用文档https://opentiny.design/tiny-engine#/help-center/course/engine
- 演示应用https://opentiny.design/tiny-engine#/tiny-engine-editor
## 开发
### 安装所需的依赖
```sh
$ npm install
$ pushd mockServer
$ npm install
$ popd
$ pnpm install
```
### 本地开发,启动本地 mock 服务器,使用本地 mock 服务器的 mock 数据
```sh
$ npm run serve
$ pnpm dev
```
# 另起一个终端
$ cd mockServer
$ npm run dev
### 本地开发直连本地的tiny-engine-webservice服务端
1. 启动 <a href="https://github.com/opentiny/tiny-engine-data-center/blob/main/README.md" target="_blank">tiny-engine-data-center</a>
2. 启动 <a href="https://github.com/opentiny/tiny-engine-webservice/blob/main/README.md" target="_blank">tiny-engine-webservice</a>
3. 修改 tiny-engine 项目 `packages/design-core/` 目录下 `vite.config.js` 中origin的值为自己本地webService项目的地址端口webService端口默认为7011
<img alt="修改端口" src="https://res.hc-cdn.com/lowcode-portal/1.1.55/img/docimg/backend_deploy_5.png">
### 物料同步[方案](https://opentiny.design/tiny-engine#/help-center/course/engine/56)
```sh
$ pnpm splitMaterials
```
```sh
$ pnpm buildMaterials
```
浏览器打开:`http://localhost:8080/?type=app&id=918&tenant=1&pageid=NTJ4MjvqoVj8OVsc`
@ -45,42 +64,35 @@ $ npm run dev
- `type=app` 应用类型
- `id=xxx` 应用 ID
- `tenant=xxx` 组织 ID
- `pagdId=xxx` 页面 ID
- `pageid=xxx` 页面 ID
## 构建
```sh
# 先构建所有插件
npm run build:plugin
pnpm run build:plugin
# 构建设计器
npm run build:alpha 或 build:prod
# 发布所有插件
npm run publish:plugin
# 发布设计器
npm run publish:core
pnpm run build:alpha 或 build:prod
```
## 常规发包流程
1. 发布插件
npm run build:plugin && npm run publish:plugin
2. 发布设计器
a) 修改包名和版本号:
包名:@opentiny/tinybuilder-design-core-test
版本号:末位每次+1, 例如:
构建后产物所在文件夹
```
"name": "@opentiny/tinybuilder-design-core-test",
"version": "1.0.87",
tiny-engine/packages/design-core/dist/
```
b) npm publish
## 里程碑
```mermaid
gantt
dateFormat YYYY-MM-DD
axisFormat %Y-%m-%d
1.0.0-beta.x version :active,2023-09-25, 2024-03-31
1.0.0-rc version : 2024-04-01, 2024-06-30
1.0.0 version : 2024-07-01, 2024-07-31
```
## 🤝 参与贡献

View File

@ -3,71 +3,71 @@
"baseUrl": "./",
"jsx": "react",
"paths": {
"@/*": ["src/*"],
"@opentiny/tiny-engine-canvas": ["src/canvas/src/index.js"],
"@opentiny/tiny-engine-controller": ["src/controller/src/index"],
"@opentiny/tiny-engine-plugin-materials": ["src/plugins/packages/materials/index"],
"@opentiny/tiny-engine-plugin-data": ["src/plugins/packages/data/index"],
"@opentiny/tiny-engine-plugin-script": ["src/plugins/packages/script/index"],
"@opentiny/tiny-engine-plugin-tree": ["src/plugins/packages/tree/index"],
"@opentiny/tiny-engine-plugin-help": ["src/plugins/packages/help/index"],
"@opentiny/tiny-engine-plugin-schema": ["src/plugins/packages/schema/index"],
"@opentiny/tiny-engine-plugin-page": ["src/plugins/packages/page/index"],
"@opentiny/tiny-engine-plugin-i18n": ["src/plugins/packages/i18n/index"],
"@opentiny/tiny-engine-plugin-bridge": ["src/plugins/packages/bridge/index"],
"@opentiny/tiny-engine-setting-events": ["src/settings/packages/events/index"],
"@opentiny/tiny-engine-setting-props": ["src/settings/packages/props/index"],
"@opentiny/tiny-engine-common": ["src/common/index"],
"@opentiny/tiny-engine-setting-styles": ["src/settings/packages/styles/index"],
"@opentiny/tiny-engine-toolbar-breadcrumb": ["src/toolbars/packages/breadcrumb/index"],
"@opentiny/tiny-engine-toolbar-fullscreen": ["src/toolbars/packages/fullscreen/index"],
"@opentiny/tiny-engine-toolbar-lang": ["src/toolbars/packages/lang/index"],
"@opentiny/tiny-engine-toolbar-layout": ["src/toolbars/packages/layout/index"],
"@opentiny/tiny-engine-toolbar-checkinout": ["src/toolbars/packages/lock/index"],
"@opentiny/tiny-engine-toolbar-logo": ["src/toolbars/packages/logo/index"],
"@opentiny/tiny-engine-toolbar-media": ["src/toolbars/packages/media/index"],
"@opentiny/tiny-engine-toolbar-preview": ["src/toolbars/packages/preview/index"],
"@opentiny/tiny-engine-toolbar-generate-vue": ["src/toolbars/packages/generate-vue/index"],
"@opentiny/tiny-engine-toolbar-clean": ["src/toolbars/packages/clean/index"],
"@opentiny/tiny-engine-toolbar-save": ["src/toolbars/packages/save/index"],
"tiny-engine-canvas": ["src/canvas/index"],
"@opentiny/tiny-engine-theme-dark": ["src/theme/packages/dark/index.less"],
"@opentiny/tiny-engine-theme-light": ["src/theme/packages/light/index.less"],
"@opentiny/tiny-engine-svgs": ["src/svgs/index"],
"@opentiny/tiny-engine-http": ["src/http/index"],
"@opentiny/tiny-engine-controller/*": ["src/controller/src/*"],
"@opentiny/tiny-engine-plugin-materials/*": ["src/plugins/packages/materials/*"],
"@opentiny/tiny-engine-plugin-data/*": ["src/plugins/packages/data/*"],
"@opentiny/tiny-engine-plugin-script/*": ["src/plugins/packages/script/*"],
"@opentiny/tiny-engine-plugin-tree/*": ["src/plugins/packages/tree/*"],
"@opentiny/tiny-engine-plugin-help/*": ["src/plugins/packages/help/*"],
"@opentiny/tiny-engine-plugin-schema/*": ["src/plugins/packages/schema/*"],
"@opentiny/tiny-engine-plugin-page/*": ["src/plugins/packages/page/*"],
"@opentiny/tiny-engine-plugin-i18n/*": ["src/plugins/packages/i18n/*"],
"@opentiny/tiny-engine-plugin-bridge/*": ["src/plugins/packages/bridge/*"],
"@opentiny/tiny-engine-setting-events/*": ["src/settings/packages/events/*"],
"@opentiny/tiny-engine-setting-props/*": ["src/settings/packages/props/*"],
"@opentiny/tiny-engine-common/*": ["src/common/*"],
"@opentiny/tiny-engine-setting-styles/*": ["src/settings/packages/styles/*"],
"@opentiny/tiny-engine-toolbar-breadcrumb/*": ["src/toolbars/packages/breadcrumb/*"],
"@opentiny/tiny-engine-toolbar-fullscreen/*": ["src/toolbars/packages/fullscreen/*"],
"@opentiny/tiny-engine-toolbar-lang/*": ["src/toolbars/packages/lang/*"],
"@opentiny/tiny-engine-toolbar-layout/*": ["src/toolbars/packages/layout/*"],
"@opentiny/tiny-engine-toolbar-checkinout/*": ["src/toolbars/packages/lock/*"],
"@opentiny/tiny-engine-toolbar-logo/*": ["src/toolbars/packages/logo/*"],
"@opentiny/tiny-engine-toolbar-media/*": ["src/toolbars/packages/media/*"],
"@opentiny/tiny-engine-toolbar-preview/*": ["src/toolbars/packages/preview/*"],
"@opentiny/tiny-engine-toolbar-clean/*": ["src/toolbars/packages/clean/*"],
"@opentiny/tiny-engine-toolbar-save/*": ["src/toolbars/packages/save/*"],
"@opentiny/tiny-engine-theme-dark/*": ["src/theme/packages/dark/*"],
"@opentiny/tiny-engine-theme-light/*": ["src/theme/packages/light/*"],
"@opentiny/tiny-engine-svgs/*": ["src/svgs/*"],
"@opentiny/tiny-engine-http/*": ["src/http/*"],
"@opentiny/tiny-engine-utils": ["src/utils/src/index.js"],
"@opentiny/tiny-engine-webcomponent-core": ["src/webcomponent/src/lib"],
"@opentiny/tiny-engine-i18n-host": ["src/i18n/src/lib"]
"@/*": ["packages/*"],
"@opentiny/tiny-engine-canvas": ["packages/canvas/src/index.js"],
"@opentiny/tiny-engine-controller": ["packages/controller/src/index"],
"@opentiny/tiny-engine-plugin-materials": ["packages/plugins/materials/index"],
"@opentiny/tiny-engine-plugin-data": ["packages/plugins/data/index"],
"@opentiny/tiny-engine-plugin-script": ["packages/plugins/script/index"],
"@opentiny/tiny-engine-plugin-tree": ["packages/plugins/tree/index"],
"@opentiny/tiny-engine-plugin-help": ["packages/plugins/help/index"],
"@opentiny/tiny-engine-plugin-schema": ["packages/plugins/schema/index"],
"@opentiny/tiny-engine-plugin-page": ["packages/plugins/page/index"],
"@opentiny/tiny-engine-plugin-i18n": ["packages/plugins/i18n/index"],
"@opentiny/tiny-engine-plugin-bridge": ["packages/plugins/bridge/index"],
"@opentiny/tiny-engine-setting-events": ["packages/settings/events/index"],
"@opentiny/tiny-engine-setting-props": ["packages/settings/props/index"],
"@opentiny/tiny-engine-common": ["packages/common/index"],
"@opentiny/tiny-engine-setting-styles": ["packages/settings/styles/index"],
"@opentiny/tiny-engine-toolbar-breadcrumb": ["packages/toolbars/breadcrumb/index"],
"@opentiny/tiny-engine-toolbar-fullscreen": ["packages/toolbars/fullscreen/index"],
"@opentiny/tiny-engine-toolbar-lang": ["packages/toolbars/lang/index"],
"@opentiny/tiny-engine-toolbar-layout": ["packages/toolbars/layout/index"],
"@opentiny/tiny-engine-toolbar-checkinout": ["packages/toolbars/lock/index"],
"@opentiny/tiny-engine-toolbar-logo": ["packages/toolbars/logo/index"],
"@opentiny/tiny-engine-toolbar-media": ["packages/toolbars/media/index"],
"@opentiny/tiny-engine-toolbar-preview": ["packages/toolbars/preview/index"],
"@opentiny/tiny-engine-toolbar-generate-vue": ["packages/toolbars/generate-vue/index"],
"@opentiny/tiny-engine-toolbar-clean": ["packages/toolbars/clean/index"],
"@opentiny/tiny-engine-toolbar-save": ["packages/toolbars/save/index"],
"tiny-engine-canvas": ["packages/canvas/index"],
"@opentiny/tiny-engine-theme-dark": ["packages/theme/dark/index.less"],
"@opentiny/tiny-engine-theme-light": ["packages/theme/light/index.less"],
"@opentiny/tiny-engine-svgs": ["packages/svgs/index"],
"@opentiny/tiny-engine-http": ["packages/http/index"],
"@opentiny/tiny-engine-controller/*": ["packages/controller/src/*"],
"@opentiny/tiny-engine-plugin-materials/*": ["packages/plugins/materials/*"],
"@opentiny/tiny-engine-plugin-data/*": ["packages/plugins/data/*"],
"@opentiny/tiny-engine-plugin-script/*": ["packages/plugins/script/*"],
"@opentiny/tiny-engine-plugin-tree/*": ["packages/plugins/tree/*"],
"@opentiny/tiny-engine-plugin-help/*": ["packages/plugins/help/*"],
"@opentiny/tiny-engine-plugin-schema/*": ["packages/plugins/schema/*"],
"@opentiny/tiny-engine-plugin-page/*": ["packages/plugins/page/*"],
"@opentiny/tiny-engine-plugin-i18n/*": ["packages/plugins/i18n/*"],
"@opentiny/tiny-engine-plugin-bridge/*": ["packages/plugins/bridge/*"],
"@opentiny/tiny-engine-setting-events/*": ["packages/settings/events/*"],
"@opentiny/tiny-engine-setting-props/*": ["packages/settings/props/*"],
"@opentiny/tiny-engine-common/*": ["packages/common/*"],
"@opentiny/tiny-engine-setting-styles/*": ["packages/settings/styles/*"],
"@opentiny/tiny-engine-toolbar-breadcrumb/*": ["packages/toolbars/breadcrumb/*"],
"@opentiny/tiny-engine-toolbar-fullscreen/*": ["packages/toolbars/fullscreen/*"],
"@opentiny/tiny-engine-toolbar-lang/*": ["packages/toolbars/lang/*"],
"@opentiny/tiny-engine-toolbar-layout/*": ["packages/toolbars/layout/*"],
"@opentiny/tiny-engine-toolbar-checkinout/*": ["packages/toolbars/lock/*"],
"@opentiny/tiny-engine-toolbar-logo/*": ["packages/toolbars/logo/*"],
"@opentiny/tiny-engine-toolbar-media/*": ["packages/toolbars/media/*"],
"@opentiny/tiny-engine-toolbar-preview/*": ["packages/toolbars/preview/*"],
"@opentiny/tiny-engine-toolbar-clean/*": ["packages/toolbars/clean/*"],
"@opentiny/tiny-engine-toolbar-save/*": ["packages/toolbars/save/*"],
"@opentiny/tiny-engine-theme-dark/*": ["packages/theme/dark/*"],
"@opentiny/tiny-engine-theme-light/*": ["packages/theme/light/*"],
"@opentiny/tiny-engine-svgs/*": ["packages/svgs/*"],
"@opentiny/tiny-engine-http/*": ["packages/http/*"],
"@opentiny/tiny-engine-utils": ["packages/utils/src/index.js"],
"@opentiny/tiny-engine-webcomponent-core": ["packages/webcomponent/src/lib"],
"@opentiny/tiny-engine-i18n-host": ["packages/i18n/src/lib"]
}
},
"include": ["src/**/*"],
"include": ["packages/**/*"],
"exclude": ["node_modules", "dist"]
}

View File

@ -1,11 +1,15 @@
{
"packages": [
"src/*",
"src/plugins/packages/*",
"src/settings/packages/*",
"src/theme/packages/*",
"src/toolbars/packages/*"
],
"command": {
"version": {
"message": "chore(release): publish"
}
},
"useNx": false,
"version": "independent"
"version": "independent",
"npmClient": "pnpm",
"publish": {
"npmClient": "pnpm"
},
"ignoreChanges": ["**/*.md", "**/test/**", ".npmrc"],
"granularPathspec": false
}

View File

@ -1,4 +1,4 @@
module.exports = {
'./src/**/**.{js,vue,jsx}': 'eslint',
'./src/**/**.{vue,js,ts,html,json,less}': 'prettier --write'
'./packages/**/**.{js,vue,jsx}': 'eslint',
'./packages/**/**.{vue,js,ts,html,json,less}': 'prettier --write'
}

44
logo.svg Normal file
View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="189px" height="38px" viewBox="0 0 189 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>logo-top</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFCC00" offset="0%"></stop>
<stop stop-color="#FF9D00" offset="100%"></stop>
</linearGradient>
<linearGradient x1="41.5583977%" y1="684.931472%" x2="57.6489702%" y2="214.83809%" id="linearGradient-2">
<stop stop-color="#5073E5" offset="0%"></stop>
<stop stop-color="#5E7CE0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="44.74774%" y1="89.3284133%" x2="67.1281333%" y2="0%" id="linearGradient-3">
<stop stop-color="#5073E5" offset="0%"></stop>
<stop stop-color="#5E7CE0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="42.185134%" y1="684.931472%" x2="57.0810819%" y2="214.83809%" id="linearGradient-4">
<stop stop-color="#5073E5" offset="0%"></stop>
<stop stop-color="#5E7CE0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="24.3954947%" y1="56.7227863%" x2="68.844278%" y2="32.8834171%" id="linearGradient-5">
<stop stop-color="#FFFFFF" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#566DB8" offset="100%"></stop>
</linearGradient>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Tiny-Design-首页" transform="translate(-106.000000, -20.000000)">
<g id="导航" transform="translate(0.000000, 1.000000)">
<g id="logo-top" transform="translate(106.000000, 19.000000)">
<text id="OpenTiny" font-family="HiraginoSans-W7, Hiragino Sans" font-size="21" font-weight="bold" fill="#242424">
<tspan x="76.2305" y="24">OpenTiny</tspan>
</text>
<g id="编组-21">
<polygon id="路径" fill="url(#linearGradient-1)" points="61 1.99723278 44.8967008 0 20.1759284 1.37793579 32.933574 3.7061054"></polygon>
<polygon id="路径" fill="url(#linearGradient-2)" points="50.0936029 6.53938911 50.0817739 30.0300979 61 27.7599874 60.9645128 5.58721999"></polygon>
<polygon id="路径" fill="url(#linearGradient-3)" points="32.9710327 33.587185 45.3264901 31.154509 45.3304331 6.99805594 32.9197734 7.92893672"></polygon>
<polygon id="路径" fill="url(#linearGradient-4)" points="20.1759284 4.76471618 20.2212732 25.8982258 32.4801266 33.3936547 32.4584399 7.93"></polygon>
<polygon id="路径" fill="url(#linearGradient-5)" points="20.1759284 25.9101141 9.22524348e-13 29.863332 11.645719 38 32.9710327 33.587185"></polygon>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -26,7 +26,7 @@ const cacheStringFunction = (fn) => {
}
const hyphenateRE = /\B([A-Z])/g
const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase())
var _export_sfc = (sfc, props) => {
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc
for (const [key, val] of props) {
target[key] = val
@ -73,7 +73,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
])
)
}
var block = /* @__PURE__ */ _export_sfc(_sfc_main, [
const block = /* @__PURE__ */ _export_sfc(_sfc_main, [
['render', _sfc_render],
['__file', 'D:/tmp/buildground/buildground_1673597935715/src/block/generated/components/PortalBlock.vue']
])

View File

@ -11,25 +11,27 @@
*/
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory(
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = factory(
require('@opentiny/tiny-engine-webcomponent-core'),
require('vue'),
require('vue-i18n'),
require('@opentiny/vue-icon')
))
: typeof define === 'function' && define.amd
? define(['@opentiny/tiny-engine-webcomponent-core', 'vue', 'vue-i18n', '@opentiny/vue-icon'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.TinyVueBlock = factory(global.TinyWebcomponentCore, global.Vue, global.VueI18n, global.TinyVueIcon)))
})(this, function (tinyWebcomponentCore, vue, vueI18n, tinyVue3Icon) {
)
} else if (typeof define === 'function' && define.amd) {
define(['@opentiny/tiny-engine-webcomponent-core', 'vue', 'vue-i18n', '@opentiny/vue-icon'], factory)
} else {
;(global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.TinyVueBlock = factory(global.TinyWebcomponentCore, global.Vue, global.VueI18n, global.TinyVueIcon))
}
})(this, (tinyWebcomponentCore, vue, vueI18n, tinyVue3Icon) => {
function _interopNamespace(e) {
if (e && e.__esModule) return e
var n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } })
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } })
if (e) {
Object.keys(e).forEach(function (k) {
Object.keys(e).forEach((k) => {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k)
const d = Object.getOwnPropertyDescriptor(e, k)
Object.defineProperty(
n,
k,
@ -45,10 +47,10 @@
}
})
}
n['default'] = e
n.default = e
return Object.freeze(n)
}
var vue__namespace = /* @__PURE__ */ _interopNamespace(vue)
const vue__namespace = /* @__PURE__ */ _interopNamespace(vue)
Object.freeze({})
Object.freeze([])
const cacheStringFunction = (fn) => {
@ -60,7 +62,7 @@
}
const hyphenateRE = /\B([A-Z])/g
const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase())
var _export_sfc = (sfc, props) => {
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc
for (const [key, val] of props) {
target[key] = val
@ -112,7 +114,7 @@
])
)
}
var block = /* @__PURE__ */ _export_sfc(_sfc_main, [
const block = /* @__PURE__ */ _export_sfc(_sfc_main, [
['render', _sfc_render],
['__file', 'D:/tmp/buildground/buildground_1673597935715/src/block/generated/components/PortalBlock.vue']
])

View File

@ -76,6 +76,6 @@ const Mapper = {
TinyDropdown: Dropdown,
TinyChartHistogram: ChartHistogram
}
Mapper['TinyTabs'].isGroup = true
Mapper['TinyGrid'].isGroup = true
Mapper.TinyTabs.isGroup = true
Mapper.TinyGrid.isGroup = true
export { Mapper as default }

View File

@ -1,23 +1,25 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory(require('@opentiny/vue')))
: typeof define === 'function' && define.amd
? define(['@opentiny/vue'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.TinyLowcodeComponent = factory(global.TinyVue)))
})(this, function (tinyVue3) {
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = factory(require('@opentiny/vue'))
} else if (typeof define === 'function' && define.amd) {
define(['@opentiny/vue'], factory)
} else {
;(global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.TinyLowcodeComponent = factory(global.TinyVue))
}
})(this, (tinyVue3) => {
'use strict'
const Mapper = {
TinyCarouselItem: tinyVue3.CarouselItem,
@ -52,7 +54,7 @@
TinyDropdown: tinyVue3.Dropdown,
TinyChartHistogram: tinyVue3.ChartHistogram
}
Mapper['TinyTabs'].isGroup = true
Mapper['TinyGrid'].isGroup = true
Mapper.TinyTabs.isGroup = true
Mapper.TinyGrid.isGroup = true
return Mapper
})

View File

@ -42,9 +42,9 @@ const cacheStringFunction = (fn) => {
}
const hyphenateRE = /\B([A-Z])/g
const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase())
var _style_0 =
const _style_0 =
'\n.team-list-item.active[data-v-b66e3972] {\r\n border: 1px solid #38acff;\n}\n.toolbars-item[data-v-b66e3972]:hover {\r\n cursor: pointer;\r\n background-color: #f1f2f3;\n}\n.toolbars-item.active[data-v-b66e3972] {\r\n background-color: #e5e6e8;\n}\n'
var _export_sfc = (sfc, props) => {
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc
for (const [key, val] of props) {
target[key] = val
@ -406,7 +406,7 @@ const _hoisted_22 = /* @__PURE__ */ _withScopeId(() =>
)
)
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
var _a
let _a
const _component_tiny_icon_setting = resolveComponent('tiny-icon-setting')
const _component_tiny_tooltip = resolveComponent('tiny-tooltip')
const _component_tiny_icon_check_out = resolveComponent('tiny-icon-check-out')
@ -640,7 +640,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
])
)
}
var block = /* @__PURE__ */ _export_sfc(_sfc_main, [
const block = /* @__PURE__ */ _export_sfc(_sfc_main, [
['render', _sfc_render],
['styles', [_style_0]],
['__scopeId', 'data-v-b66e3972'],

View File

@ -11,36 +11,41 @@
*/
;(function (global, factory) {
typeof exports === 'object ' && typeof module !== 'undefined '
? (module.exports = factory(
require('@opentiny/tiny-engine-webcomponent-core '),
require('vue '),
require('vue-i18n '),
require('@opentiny/vue-icon '),
require('@opentiny/vue ')
))
: typeof define === 'function ' && define.amd
? define(
['@opentiny/tiny-engine-webcomponent-core ', 'vue ', 'vue-i18n ', '@opentiny/vue-icon ', '@opentiny/vue '],
factory
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = factory(
require('@opentiny/tiny-engine-webcomponent-core'),
require('vue'),
require('vue-i18n'),
require('@opentiny/vue-icon'),
require('@opentiny/vue')
)
: ((global = typeof globalThis !== 'undefined ' ? globalThis : global || self),
} else if (typeof define === 'function ' && define.amd) {
define([
'@opentiny/tiny-engine-webcomponent-core',
'vue',
'vue-i18n',
'@opentiny/vue-icon',
'@opentiny/vue'
], factory)
} else {
;(global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.TinyVueBlock = factory(
global.TinyWebcomponentCore,
global.Vue,
global.VueI18n,
global.TinyVueIcon,
global.TinyVue
)))
})(this, function (tinyWebcomponentCore, vue, vueI18n, tinyVue3Icon, tinyVue3) {
))
}
})(this, (tinyWebcomponentCore, vue, vueI18n, tinyVue3Icon, tinyVue3) => {
'use strict '
function _interopNamespace(e) {
if (e && e.__esModule) return e
var n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module ' } })
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module ' } })
if (e) {
Object.keys(e).forEach(function (k) {
Object.keys(e).forEach((k) => {
if (k !== 'default ') {
var d = Object.getOwnPropertyDescriptor(e, k)
const d = Object.getOwnPropertyDescriptor(e, k)
Object.defineProperty(
n,
k,
@ -59,7 +64,7 @@
n['default '] = e
return Object.freeze(n)
}
var vue__namespace = /* @__PURE__ */ _interopNamespace(vue)
const vue__namespace = /* @__PURE__ */ _interopNamespace(vue)
Object.freeze({})
Object.freeze([])
const cacheStringFunction = (fn) => {
@ -71,9 +76,9 @@
}
const hyphenateRE = /\B([A-Z])/g
const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1 ').toLowerCase())
var _style_0 =
const _style_0 =
'\n.team-list-item.active[data-v-b66e3972] {\r\n border: 1px solid #38acff;\n}\n.toolbars-item[data-v-b66e3972]:hover {\r\n cursor: pointer;\r\n background-color: #f1f2f3;\n}\n.toolbars-item.active[data-v-b66e3972] {\r\n background-color: #e5e6e8;\n}\n '
var _export_sfc = (sfc, props) => {
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc
for (const [key, val] of props) {
target[key] = val
@ -446,7 +451,7 @@
)
)
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
var _a
let _a
const _component_tiny_icon_setting = vue.resolveComponent('tiny-icon-setting ')
const _component_tiny_tooltip = vue.resolveComponent('tiny-tooltip ')
const _component_tiny_icon_check_out = vue.resolveComponent('tiny-icon-check-out ')
@ -688,7 +693,7 @@
])
)
}
var block = /* @__PURE__ */ _export_sfc(_sfc_main, [
const block = /* @__PURE__ */ _export_sfc(_sfc_main, [
['render ', _sfc_render],
['styles ', [_style_0]],
['__scopeId ', 'data-v-b66e3972 '],

View File

@ -6065,7 +6065,7 @@
"devMode": "proCode",
"npm": {
"package": "@opentiny/vue",
"exportName": "TinyTabItem",
"exportName": "TabItem",
"version": "",
"destructuring": true
},
@ -6314,7 +6314,7 @@
"devMode": "proCode",
"npm": {
"package": "@opentiny/vue",
"exportName": "TinyBreadcrumbItem",
"exportName": "BreadcrumbItem",
"version": "",
"destructuring": true
},

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
module.exports = {
port: process.env.MOCK_PORT || 9090,
env: process.env.NODE_ENV || 'development' // Current mode
}

View File

@ -1,9 +1,21 @@
{
"name": "koa2-mock",
"version": "1.0.0",
"name": "@opentiny/tiny-engine-mock",
"version": "1.0.3",
"publishConfig": {
"access": "public"
},
"description": "mock服务",
"author": "opentiny",
"license": "WTFPL",
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
"directory": "mockServer"
},
"bugs": {
"url": "https://github.com/opentiny/tiny-engine/issues"
},
"author": "OpenTiny Team",
"license": "MIT",
"homepage": "https://opentiny.design/tiny-engine",
"scripts": {
"start": "gulp nodemon",
"dev": "gulp",
@ -13,7 +25,7 @@
"lint": "eslint --fix ."
},
"dependencies": {
"@opentiny/lowcode-dsl-vue": "0.4.0",
"@opentiny/tiny-engine-dsl-vue": "^1.0.3",
"@seald-io/nedb": "^4.0.2",
"fs-extra": "^11.1.1",
"glob": "^10.3.4",

View File

@ -14,13 +14,12 @@ import Koa2 from 'koa'
import KoaBody from 'koa-body'
import KoaStatic from 'koa-static2'
import path from 'path'
import MainRoutes from './routes/main-routes'
import { env, port } from '../config/config'
import ErrorRoutesCatch from './middleware/ErrorRoutesCatch'
import ErrorRoutes from './routes/error-routes'
import MainRoutes from './routes/main-routes'
const app = new Koa2()
const env = process.env.NODE_ENV || 'development' // Current mode
const PORT = 9090
app
.use((ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*')
@ -57,6 +56,6 @@ if (env === 'development') {
})
}
app.listen(PORT)
app.listen(port)
export default app

View File

@ -0,0 +1,3 @@
{"id":"L0fyFYECrNiRZMiX","app":{"id":918,"name":"portal-app","app_website":null,"platform":{"id":897,"name":"portal-platform"},"obs_url":"","created_by":null,"updated_by":null,"created_at":"2022-06-08T07:19:01.000Z","updated_at":"2023-09-04T08:55:40.000Z","state":null,"published":false,"createdBy":86,"updatedBy":564,"tenant":1,"home_page":"NTJ4MjvqoVj8OVsc","css":null,"config":{},"git_group":"","project_name":"","constants":null,"data_handler":{"type":"JSFunction","value":"function dataHanlder(res){\n return res;\n}"},"description":"demo应用","latest":22,"platform_history":null,"editor_url":"","branch":"develop","visit_url":null,"is_demo":null,"image_url":"","is_default":true,"template_type":null,"set_template_time":null,"set_template_by":null,"set_default_by":169,"framework":"Vue","global_state":[],"default_lang":null,"extend_config":{"business":{"serviceName":"","endpointName":"cce","endpointId":"ee","serviceId":"ee","router":"ee"},"env":{"alpha":{"regions":[{"name":"","baseUrl":"","isDefault":false}],"isDefault":true}},"type":"console"},"assets_url":"","data_hash":"ae128e37f6bc378f1b9c21d75bd05551","can_associate":true,"data_source_global":{"dataHandler":{"type":"JSFunction","value":"function dataHanlder(res){\n return res;\n}"}}},"name":"我的分类","desc":"","blocks":["ALvDb0JD8atzd3nA"],"category_id":"qukuaifenlei","_id":"L0fyFYECrNiRZMiX"}
{"$$indexCreated":{"fieldName":"name","unique":true,"sparse":false}}
{"$$indexCreated":{"fieldName":"name","unique":true}}

View File

@ -0,0 +1,3 @@
{"id":"b57MCCORYPGjgL23","app":{"id":918,"name":"portal-app","app_website":null,"platform":{"id":897,"name":"portal-platform"},"obs_url":"","created_by":null,"updated_by":null,"created_at":"2022-06-08T07:19:01.000Z","updated_at":"2023-09-04T08:55:40.000Z","state":null,"published":false,"createdBy":86,"updatedBy":564,"tenant":1,"home_page":"NTJ4MjvqoVj8OVsc","css":null,"config":{},"git_group":"","project_name":"","constants":null,"data_handler":{"type":"JSFunction","value":"function dataHanlder(res){\n return res;\n}"},"description":"demo应用","latest":22,"platform_history":null,"editor_url":"","branch":"develop","visit_url":null,"is_demo":null,"image_url":"","is_default":true,"template_type":null,"set_template_time":null,"set_template_by":null,"set_default_by":169,"framework":"Vue","global_state":[],"default_lang":null,"extend_config":{"business":{"serviceName":"","endpointName":"cce","endpointId":"ee","serviceId":"ee","router":"ee"},"env":{"alpha":{"regions":[{"name":"","baseUrl":"","isDefault":false}],"isDefault":true}},"type":"console"},"assets_url":"","data_hash":"ae128e37f6bc378f1b9c21d75bd05551","can_associate":true,"data_source_global":{"dataHandler":{"type":"JSFunction","value":"function dataHanlder(res){\n return res;\n}"}}},"name":"我的区块","desc":"","blocks":["ALvDb0JD8atzd3nA"],"_id":"b57MCCORYPGjgL23"}
{"$$indexCreated":{"fieldName":"name","unique":true,"sparse":false}}
{"$$indexCreated":{"fieldName":"name","unique":true}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -102,7 +102,7 @@
"type": "function",
"content": {
"type": "JSFunction",
"value": "function util() {\r\n console.log(3211)\r\n}"
"value": "function test() {\r\n return 'test'\r\n}"
},
"app": 918,
"category": "utils",

File diff suppressed because it is too large Load Diff

View File

@ -1,503 +0,0 @@
{
"data": [
{
"id": 81,
"name": "test",
"app": {
"id": 918,
"name": "portal-app",
"app_website": null,
"platform": 897,
"obs_url": "",
"created_at": "2022-06-08T07:19:01.000Z",
"updated_at": "2023-08-23T02:22:28.000Z",
"state": null,
"published": false,
"createdBy": 86,
"tenant": 1,
"home_page": "1761",
"css": null,
"config": {},
"git_group": "",
"project_name": "",
"constants": null,
"data_handler": {
"type": "JSFunction",
"value": "function dataHanlder(res){\n return res;\n}"
},
"description": "demo应用",
"latest": 22,
"platform_history": null,
"editor_url": "http://localhost:9090/platform-center/entry/portal-platform?type=app&id=918",
"branch": "develop",
"visit_url": null,
"is_demo": null,
"image_url": "http://localhost:9090/assets/images/27f7f9d26edd98f6bb1ed8d594d408d9_100x100.jpg",
"is_default": true,
"template_type": null,
"set_template_time": null,
"set_template_by": null,
"framework": "Vue",
"global_state": [
{
"id": "test1",
"state": {
"testa": 1
},
"getters": {},
"actions": {}
},
{
"id": "test2",
"state": {
"name1": "xxx1"
},
"getters": {
"count": {
"type": "JSFunction",
"value": "function count() {}"
}
},
"actions": {
"actions": {
"type": "JSFunction",
"value": "function actions() {}"
}
}
},
{
"id": "test3",
"state": {
"name1": "xxx"
},
"getters": {
"count": {
"type": "JSFunction",
"value": "function count() {}"
}
},
"actions": {
"actions": {
"type": "JSFunction",
"value": "function actions() {}"
}
}
},
{
"id": "test4",
"state": {
"region": "",
"scenario": "all",
"productId": "",
"planId": "",
"addEvs": false,
"addHss": false,
"addCbr": false,
"period": {
"value": 1,
"unit": "month"
},
"amount": 1
},
"getters": {},
"actions": {}
}
],
"default_lang": null,
"extend_config": {
"business": {
"serviceName": "",
"endpointName": "cce",
"endpointId": "ee",
"serviceId": "ee",
"router": "ee"
},
"env": {
"alpha": {
"regions": [
{
"name": "",
"baseUrl": "",
"isDefault": false
}
],
"isDefault": true
}
},
"type": "console"
},
"assets_url": "",
"data_hash": "d15fe133765a70ee503c9643a329f0db",
"can_associate": true,
"data_source_global": {
"dataHandler": {
"type": "JSFunction",
"value": "function dataHanlder(res){\n return res;\n}"
}
}
},
"desc": null,
"createdBy": {
"id": 86,
"username": "开发者",
"email": "developer@lowcode.com",
"resetPasswordToken": "developer",
"blocked": null,
"created_at": "2022-05-27T16:50:44.000Z",
"updated_at": "2022-05-27T16:50:44.000Z",
"block": null,
"is_admin": true,
"is_public": null
},
"updatedBy": {
"id": 86,
"username": "开发者",
"email": "developer@lowcode.com",
"resetPasswordToken": "developer",
"blocked": null,
"created_at": "2022-05-27T16:50:44.000Z",
"updated_at": "2022-05-27T16:50:44.000Z",
"block": null,
"is_admin": true,
"is_public": null
},
"created_at": "2023-06-12T00:49:54.000Z",
"updated_at": "2023-06-12T00:49:54.000Z",
"category_id": "test",
"blocks": []
},
{
"id": 82,
"name": "test_mChange",
"app": {
"id": 918,
"name": "portal-app",
"app_website": null,
"platform": 897,
"obs_url": "",
"created_at": "2022-06-08T07:19:01.000Z",
"updated_at": "2023-08-23T02:22:28.000Z",
"state": null,
"published": false,
"createdBy": 86,
"tenant": 1,
"home_page": "1761",
"css": null,
"config": {},
"git_group": "",
"project_name": "",
"constants": null,
"data_handler": {
"type": "JSFunction",
"value": "function dataHanlder(res){\n return res;\n}"
},
"description": "demo应用",
"latest": 22,
"platform_history": null,
"editor_url": "http://localhost:9090/platform-center/entry/portal-platform?type=app&id=918",
"branch": "develop",
"visit_url": null,
"is_demo": null,
"image_url": "http://localhost:9090/assets/images/27f7f9d26edd98f6bb1ed8d594d408d9_100x100.jpg",
"is_default": true,
"template_type": null,
"set_template_time": null,
"set_template_by": null,
"framework": "Vue",
"global_state": [
{
"id": "test1",
"state": {
"testa": 1
},
"getters": {},
"actions": {}
},
{
"id": "test2",
"state": {
"name1": "xxx1"
},
"getters": {
"count": {
"type": "JSFunction",
"value": "function count() {}"
}
},
"actions": {
"actions": {
"type": "JSFunction",
"value": "function actions() {}"
}
}
},
{
"id": "test3",
"state": {
"name1": "xxx"
},
"getters": {
"count": {
"type": "JSFunction",
"value": "function count() {}"
}
},
"actions": {
"actions": {
"type": "JSFunction",
"value": "function actions() {}"
}
}
},
{
"id": "test4",
"state": {
"region": "",
"scenario": "all",
"productId": "",
"planId": "",
"addEvs": false,
"addHss": false,
"addCbr": false,
"period": {
"value": 1,
"unit": "month"
},
"amount": 1
},
"getters": {},
"actions": {}
}
],
"default_lang": null,
"extend_config": {
"business": {
"serviceName": "",
"endpointName": "cce",
"endpointId": "ee",
"serviceId": "ee",
"router": "ee"
},
"env": {
"alpha": {
"regions": [
{
"name": "",
"baseUrl": "",
"isDefault": false
}
],
"isDefault": true
}
},
"type": "console"
},
"assets_url": "",
"data_hash": "d15fe133765a70ee503c9643a329f0db",
"can_associate": true,
"data_source_global": {
"dataHandler": {
"type": "JSFunction",
"value": "function dataHanlder(res){\n return res;\n}"
}
}
},
"desc": null,
"createdBy": {
"id": 86,
"username": "开发者",
"email": "developer@lowcode.com",
"resetPasswordToken": "developer",
"blocked": null,
"created_at": "2022-05-27T16:50:44.000Z",
"updated_at": "2022-05-27T16:50:44.000Z",
"block": null,
"is_admin": true,
"is_public": null
},
"updatedBy": {
"id": 86,
"username": "开发者",
"email": "developer@lowcode.com",
"resetPasswordToken": "developer",
"blocked": null,
"created_at": "2022-05-27T16:50:44.000Z",
"updated_at": "2022-05-27T16:50:44.000Z",
"block": null,
"is_admin": true,
"is_public": null
},
"created_at": "2023-06-12T00:50:54.000Z",
"updated_at": "2023-06-12T00:50:54.000Z",
"category_id": "test_mChange",
"blocks": []
},
{
"id": 19,
"name": "test1",
"app": {
"id": 918,
"name": "portal-app",
"app_website": null,
"platform": 897,
"obs_url": "",
"created_at": "2022-06-08T07:19:01.000Z",
"updated_at": "2023-08-23T02:22:28.000Z",
"state": null,
"published": false,
"createdBy": 86,
"tenant": 1,
"home_page": "1761",
"css": null,
"config": {},
"git_group": "",
"project_name": "",
"constants": null,
"data_handler": {
"type": "JSFunction",
"value": "function dataHanlder(res){\n return res;\n}"
},
"description": "demo应用",
"latest": 22,
"platform_history": null,
"editor_url": "http://localhost:9090/platform-center/entry/portal-platform?type=app&id=918",
"branch": "develop",
"visit_url": null,
"is_demo": null,
"image_url": "http://localhost:9090/assets/images/27f7f9d26edd98f6bb1ed8d594d408d9_100x100.jpg",
"is_default": true,
"template_type": null,
"set_template_time": null,
"set_template_by": null,
"framework": "Vue",
"global_state": [
{
"id": "test1",
"state": {
"testa": 1
},
"getters": {},
"actions": {}
},
{
"id": "test2",
"state": {
"name1": "xxx1"
},
"getters": {
"count": {
"type": "JSFunction",
"value": "function count() {}"
}
},
"actions": {
"actions": {
"type": "JSFunction",
"value": "function actions() {}"
}
}
},
{
"id": "test3",
"state": {
"name1": "xxx"
},
"getters": {
"count": {
"type": "JSFunction",
"value": "function count() {}"
}
},
"actions": {
"actions": {
"type": "JSFunction",
"value": "function actions() {}"
}
}
},
{
"id": "test4",
"state": {
"region": "",
"scenario": "all",
"productId": "",
"planId": "",
"addEvs": false,
"addHss": false,
"addCbr": false,
"period": {
"value": 1,
"unit": "month"
},
"amount": 1
},
"getters": {},
"actions": {}
}
],
"default_lang": null,
"extend_config": {
"business": {
"serviceName": "",
"endpointName": "cce",
"endpointId": "ee",
"serviceId": "ee",
"router": "ee"
},
"env": {
"alpha": {
"regions": [
{
"name": "",
"baseUrl": "",
"isDefault": false
}
],
"isDefault": true
}
},
"type": "console"
},
"assets_url": "",
"data_hash": "d15fe133765a70ee503c9643a329f0db",
"can_associate": true,
"data_source_global": {
"dataHandler": {
"type": "JSFunction",
"value": "function dataHanlder(res){\n return res;\n}"
}
}
},
"desc": null,
"createdBy": {
"id": 86,
"username": "开发者",
"email": "developer@lowcode.com",
"resetPasswordToken": "developer",
"blocked": null,
"created_at": "2022-05-27T16:50:44.000Z",
"updated_at": "2022-05-27T16:50:44.000Z",
"block": null,
"is_admin": true,
"is_public": null
},
"updatedBy": {
"id": 86,
"username": "开发者",
"email": "developer@lowcode.com",
"resetPasswordToken": "developer",
"blocked": null,
"created_at": "2022-05-27T16:50:44.000Z",
"updated_at": "2022-05-27T16:50:44.000Z",
"block": null,
"is_admin": true,
"is_public": null
},
"created_at": "2023-03-22T07:26:04.000Z",
"updated_at": "2023-06-02T08:45:34.000Z",
"category_id": "test_mChange01",
"blocks": []
}
],
"locale": "zh-cn"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,31 +1,24 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import KoaRouter from 'koa-router'
import * as glob from 'glob'
import path from 'path'
import fs from 'fs-extra'
import Schema2CodeServcice from '../services/schema2code'
import PageService from '../services/pages'
import AppService from '../services/app'
import BlockService from '../services/block'
import SourceService from '../services/source'
import * as glob from 'glob'
import KoaRouter from 'koa-router'
import path from 'path'
import MockService from '../services/mockService'
import { getResponseData } from '../tool/Common'
const router = new KoaRouter()
const schema2codeService = new Schema2CodeServcice()
export const pageService = new PageService()
export const appService = new AppService()
export const blockService = new BlockService()
export const sourceService = new SourceService()
export const mockService = new MockService()
const getJsonPathData = (jpath, method = 'get') => {
const usefulPath = jpath.split(`${method}${path.sep}`)[1]
const apipath = usefulPath.split(path.sep)
@ -63,50 +56,172 @@ glob.globSync(`${mockPath}/post/**/*.json`).forEach((jpath) => {
})
router.get('/app-center/api/apps/canvas/lock', async (ctx) => {
ctx.body = await appService.lock(ctx.request.query)
ctx.body = await mockService.appService.lock(ctx.request.query)
})
router.post('/app-center/api/schema2code', (ctx) => {
const { pageInfo } = ctx.request.body
ctx.body = schema2codeService.schema2code(pageInfo)
ctx.body = mockService.schema2codeService.schema2code(pageInfo)
})
router.get('/app-center/api/preview/metadata', (ctx) => {
ctx.body = appService.getAppPreviewMetaData()
ctx.body = mockService.appService.getAppPreviewMetaData()
})
router.post('/app-center/api/pages/create', async (ctx) => {
ctx.body = await pageService.create(ctx.request.body)
ctx.body = await mockService.pageService.create(ctx.request.body)
})
router.post('/app-center/api/pages/update/:id', async (ctx) => {
const { id } = ctx.params
const { body } = ctx.request
ctx.body = await pageService.update(id, body)
ctx.body = await mockService.pageService.update(id, body)
})
router.get('/app-center/api/pages/list/:appId', async (ctx) => {
const { appId } = ctx.params
ctx.body = await pageService.list(appId)
ctx.body = await mockService.pageService.list(appId)
})
router.get('/app-center/api/pages/detail/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await pageService.detail(id)
ctx.body = await mockService.pageService.detail(id)
})
router.get('/app-center/api/pages/delete/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await pageService.delete(id)
ctx.body = await mockService.pageService.delete(id)
})
router.get('/material-center/api/block', (ctx)=> {
ctx.body = blockService.find(ctx.request.query)
router.get('/material-center/api/block/detail/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await mockService.blockService.detail(id)
})
router.get('/material-center/api/blocks', async (ctx) => {
const { appId } = ctx.params
ctx.body = await mockService.blockService.list(appId)
})
router.post('/material-center/api/block/create', async (ctx) => {
const result = mockService.blockService.create(ctx.request.body)
const categoriesId = ctx.request.body.categories[0]
const _id = result.id
await mockService.blockCategoryService.update(categoriesId, { _id })
ctx.body = getResponseData(result)
})
router.post('/material-center/api/block/update/:id', async (ctx) => {
const { id } = ctx.params
const { body } = ctx.request
ctx.body = await mockService.blockService.update(id, body)
})
router.get('/material-center/api/block/delete/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await mockService.blockService.delete(id)
})
router.post('/material-center/api/block-groups/create', async (ctx) => {
ctx.body = await mockService.blockGroupService.create(ctx.request.body)
})
router.post('/material-center/api/block-groups/update/:id', async (ctx) => {
const { id } = ctx.params
const { body } = ctx.request
ctx.body = await mockService.blockGroupService.update(id, body)
})
router.get('/material-center/api/block-groups/delete/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await mockService.blockGroupService.delete(id)
})
router.get('/material-center/api/block-groups', async (ctx) => {
const result = await mockService.blockGroupService.find(ctx.query)
let blockGroup
if (result.data.length === 0) {
ctx.body = result
} else if (result.data.length > 1) {
blockGroup = await Promise.all(
result.data.map(async (group) => {
group.blocks = await Promise.all(
group.blocks.map(async (block) => {
const blockData = await mockService.blockService.detail(block.id)
return blockData
})
)
return group
})
)
ctx.body = getResponseData(blockGroup)
} else if (result.data.length === 1) {
blockGroup = result.data[0]
const blocks = await Promise.all(
blockGroup.blocks.map(async (item) => {
const blockData = await mockService.blockService.detail(item)
return blockData
})
)
blockGroup.blocks = blocks
ctx.body = getResponseData([blockGroup])
}
})
router.post('/material-center/api/block-categories', async (ctx) => {
ctx.body = await mockService.blockCategoryService.create(ctx.request.body)
})
router.put('/material-center/api/block-categories/:id', async (ctx) => {
const { id } = ctx.params
const { body } = ctx.request
ctx.body = await mockService.blockCategoryService.update(id, body)
})
router.delete('/material-center/api/block-categories/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await mockService.blockCategoryService.delete(id)
})
router.get('/material-center/api/block-categories', async (ctx) => {
const result = await mockService.blockCategoryService.find(ctx.query)
const blockCategories = await Promise.all(
result.data.map(async (group) => {
const blocks = await Promise.all(
group.blocks.map(async (block) => {
const blockData = await mockService.blockService.detail(block)
return blockData
})
)
group.blocks = blocks
return group
})
)
ctx.body = getResponseData(blockCategories)
})
router.get('/app-center/api/sources/detail/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await sourceService.detail(id)
ctx.body = await mockService.sourceService.detail(id)
})
router.post('/material-center/api/block/deploy', async (ctx) => {
ctx.body = await mockService.blockBuildService.build(ctx.request.body)
})
router.get('/material-center/api/tasks/:id', async (ctx) => {
const { id } = ctx.params
ctx.body = await mockService.taskService.detail(id)
})
router.get('/block-history', async (ctx) => {
const { id } = ctx.params
ctx.body = await mockService.blockHistoryService.find(id)
})
router.post('block-history/create', async (ctx) => {
ctx.body = await mockService.blockHistoryService.create(ctx.request.body)
})
export default router

View File

@ -31,7 +31,7 @@ export default class AppService {
// 拼装数据源
const dataSource = {
list: source,
dataHandler: app['data_handler']
dataHandler: app.data_handler
}
// 拼装工具类
const utils = []
@ -47,7 +47,7 @@ export default class AppService {
const i18n = this.formatI18nEntrites(entriesData)
return getResponseData({
dataSource,
globalState: app['global_state'],
globalState: app.global_state,
utils,
i18n
})

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,93 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import path from 'path'
import DateStore from '@seald-io/nedb'
import { getResponseData } from '../tool/Common'
import blocks from './blocks.json'
export default class BlockService {
find({label}) {
const blockData = blocks[label] || {}
return getResponseData(blockData)
constructor() {
this.db = new DateStore({
filename: path.resolve(__dirname, '../database/blocks.db'),
autoload: true
})
this.db.ensureIndex({
fieldName: 'label',
unique: true
})
this.userInfo = {
id: 86,
username: '开发者',
email: 'developer@lowcode.com',
resetPasswordToken: 'developer',
confirmationToken: 'dfb2c162-351f-4f44-ad5f-8998',
is_admin: true
}
this.blockModel = {
id: '',
label: '',
name_cn: '',
framework: [],
content: {},
description: '',
path: '',
screenshot: '',
created_app: '',
tags: '',
categories: [],
occupier: {
id: 86,
username: '开发者',
resetPasswordToken: 'developer'
},
isDefault: null,
isOfficial: null
}
}
async create(params) {
const blockData = { ...this.blockModel, ...params }
const result = await this.db.insertAsync(blockData)
const { _id } = result
await this.db.updateAsync({ _id }, { $set: { id: _id } })
result.id = result._id
return result
}
async update(id, params) {
await this.db.updateAsync({ _id: id }, { $set: params })
const result = await this.db.findOneAsync({ _id: id })
return getResponseData(result)
}
async detail(blockId) {
const result = await this.db.findOneAsync({ _id: blockId })
return result
}
async delete(blockId) {
const result = await this.db.findOneAsync({ _id: blockId })
await this.db.removeAsync({ _id: blockId })
return getResponseData(result)
}
async list(appId) {
const result = await this.db.findAsync()
return getResponseData(result)
}
async find(params) {
const result = await this.db.findAsync(params)
return result
}
}

View File

@ -0,0 +1,76 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import path from 'path'
import DateStore from '@seald-io/nedb'
import { getResponseData } from '../tool/Common'
import appinfo from './appinfo.json'
export default class BlockCategoryService {
constructor() {
this.db = new DateStore({
filename: path.resolve(__dirname, '../database/blockCategories.db'),
autoload: true
})
this.db.ensureIndex({
fieldName: 'name',
unique: true
})
this.blockCategoriesModel = {
id: '',
app: '',
name: '',
desc: '',
blocks: []
}
}
async create(params) {
const blockCategoriesData = { ...this.blockCategoriesModel, ...params }
blockCategoriesData.app = appinfo.app
const result = await this.db.insertAsync(blockCategoriesData)
const { _id } = result
await this.db.updateAsync({ _id }, { $set: { id: _id } })
result.id = result._id
return getResponseData(result)
}
async update(id, params) {
if (params?._id) {
const categories = await this.db.findOneAsync({ _id: id })
categories.blocks.push(params._id)
await this.db.updateAsync({ _id: id }, { $set: categories })
return getResponseData(categories)
}
params.app = appinfo.app
await this.db.updateAsync({ _id: id }, { $set: params })
const result = await this.db.findOneAsync({ _id: id })
return getResponseData(result)
}
async find(params) {
const result = await this.db.findAsync()
return getResponseData(result)
}
async delete(id) {
const result = await this.db.findOneAsync({ _id: id })
await this.db.removeAsync({ _id: id })
return getResponseData(result)
}
async list(appId) {
const result = await this.db.findAsync()
return getResponseData(result)
}
}

View File

@ -0,0 +1,75 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import path from 'path'
import DateStore from '@seald-io/nedb'
import { getResponseData } from '../tool/Common'
import appinfo from './appinfo.json'
export default class BlockGroupService {
constructor() {
this.db = new DateStore({
filename: path.resolve(__dirname, '../database/blockGroups.db'),
autoload: true
})
this.db.ensureIndex({
fieldName: 'name',
unique: true
})
this.blockGroupModel = {
id: '',
app: '',
name: '',
desc: '',
blocks: []
}
}
async create(params) {
const blockGroupData = { ...this.blockGroupModel, ...params }
blockGroupData.app = appinfo.app
const result = await this.db.insertAsync(blockGroupData)
const { _id } = result
await this.db.updateAsync({ _id }, { $set: { id: _id } })
result.id = result._id
return getResponseData(result)
}
async update(id, params) {
params.app = appinfo.app
await this.db.updateAsync({ _id: id }, { $set: params })
const result = await this.db.findOneAsync({ _id: id })
return getResponseData(result)
}
async find(params) {
if (params?.app || !params?.id) {
const result = await this.db.findAsync()
return getResponseData(result)
}
const { id } = params
const blockGroup = await this.db.findOneAsync({ _id: id })
return getResponseData([blockGroup])
}
async delete(blockGroupId) {
const result = await this.db.findOneAsync({ _id: blockGroupId })
await this.db.removeAsync({ _id: blockGroupId })
return getResponseData(result)
}
async list(appId) {
const result = await this.db.findAsync()
return getResponseData(result)
}
}

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import PageService from './pages'
import AppService from './app'
import BlockService from './block'
import SourceService from './source'
import BlockGroupService from './blockGroup'
import BlockCategoryService from './blockCategory'
import Schema2CodeServcice from './schema2code'
export default class MockService {
schema2codeService
pageService
appService
blockService
sourceService
blockGroupService
blockCategoryService
constructor() {
this.schema2codeService = new Schema2CodeServcice()
this.pageService = new PageService()
this.appService = new AppService()
this.blockService = new BlockService()
this.sourceService = new SourceService()
this.blockGroupService = new BlockGroupService()
this.blockCategoryService = new BlockCategoryService()
}
}

View File

@ -1,14 +1,14 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { pageService } from '../routes/main-routes'
import appInfo from './appinfo.json'
@ -50,7 +50,7 @@ export default class Schema2CodeServcice {
main: defaultMain
})
const { generateCode } = require('@opentiny/lowcode-dsl-vue')
const { generateCode } = require('@opentiny/tiny-engine-dsl-vue')
let code
try {
code = generateCode({
@ -84,7 +84,7 @@ export default class Schema2CodeServcice {
return components.map((component) => {
const {
component: componentName,
npm: { package: packageName, exportName, version, destructuring }
npm: { package: packageName, exportName, version, destructuring } = {}
} = component
return {
componentName,

View File

@ -1,117 +1,52 @@
{
"name": "@opentiny/tiny-engine",
"version": "1.0.0",
"description": "TinyEngine enables developers to customize low-code platforms, build low-bit platforms online in real time, and support secondary development or integration of low-bit platform capabilities.",
"homepage": "https://opentiny.design/tiny-engine",
"keywords": [
"vue",
"vue3",
"frontend",
"opentiny",
"lowcode",
"tiny-engine"
],
"name": "tiny-engine",
"private": true,
"scripts": {
"dev": "cross-env NODE_OPTIONS=--max-old-space-size=10240 VITE_API_MOCK=mock vite",
"serve": "cross-env NODE_OPTIONS=--max-old-space-size=10240 vite",
"build:plugin": "lerna run build --scope @opentiny/tiny-engine-*",
"build:alpha": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode alpha",
"build:prod": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode prod",
"preinstall": "npx only-allow pnpm",
"dev": "pnpm run setup && concurrently 'pnpm:serve:backend' 'pnpm:serve:frontend'",
"dev:mock": "pnpm --filter @opentiny/tiny-engine dev",
"serve:frontend": "pnpm --filter @opentiny/tiny-engine serve",
"serve:backend": "pnpm --filter @opentiny/tiny-engine-mock dev",
"build:plugin": "pnpm --filter @opentiny/tiny-engine-* build",
"build:alpha": "pnpm --filter @opentiny/tiny-engine build:alpha",
"build:prod": "pnpm --filter @opentiny/tiny-engine build:prod",
"buildComponentSchemas": "node scripts/buildComponentSchemas.js",
"preview": "vite preview",
"preview": "pnpm --filter @opentiny/tiny-engine preview",
"lint": "eslint . --ext .js,.vue,.jsx --fix",
"format": "prettier --write **/*{.vue,.js,.ts,.html,.json}",
"auto:publish": "node autoPublish",
"publish:core": "npm publish",
"publish:plugin": "lerna exec npm publish --scope @opentiny/tiny-engine-*",
"version": "lerna exec npm version ${version}",
"clean": "lerna clean",
"prepare": "node -e \"if(require('fs').existsSync('.git')){process.exit(1)}\" || husky install"
},
"dependencies": {
"@babel/core": "7.18.13",
"@babel/generator": "7.18.13",
"@babel/parser": "7.18.13",
"@babel/traverse": "7.18.13",
"@opentiny/vue": "~3.9.0",
"@opentiny/vue-design-smb": "~3.9.0",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/repl": "^1.3.0",
"@vueuse/core": "^9.6.0",
"element-resize-detector": "^1.2.4",
"file-saver": "^2.0.5",
"html2canvas": "^1.4.1",
"jszip": "^3.10.1",
"monaco-editor": "0.33.0",
"prettier": "2.7.1",
"sortablejs": "^1.14.0",
"vue": "3.2.45",
"vue-clipboard3": "^2.0.0",
"vue-draggable-next": "2.1.0",
"vue-i18n": "9.2.2",
"xlsx": "^0.18.5"
"prepare": "node -e \"if(require('fs').existsSync('.git')){process.exit(1)}\" || husky install",
"pub:premajor": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version premajor --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
"pub:preminor": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version preminor --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
"pub:prepatch": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version prepatch --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
"pub:prerelease": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version prerelease --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes",
"setup": "node ./scripts/setup.js",
"splitMaterials": "node ./scripts/splitMaterials.mjs",
"buildMaterials": "node ./scripts/buildMaterials.mjs"
},
"devDependencies": {
"@babel/eslint-parser": "^7.21.3",
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@opentiny/tiny-engine-canvas": "file:src/canvas",
"@opentiny/tiny-engine-common": "file:src/common",
"@opentiny/tiny-engine-controller": "file:src/controller",
"@opentiny/tiny-engine-http": "file:src/http",
"@opentiny/tiny-engine-plugin-block": "file:src/plugins/packages/block",
"@opentiny/tiny-engine-plugin-bridge": "file:src/plugins/packages/bridge",
"@opentiny/tiny-engine-plugin-data": "file:src/plugins/packages/data",
"@opentiny/tiny-engine-plugin-datasource": "file:src/plugins/packages/datasource",
"@opentiny/tiny-engine-plugin-help": "file:src/plugins/packages/help",
"@opentiny/tiny-engine-plugin-i18n": "file:src/plugins/packages/i18n",
"@opentiny/tiny-engine-plugin-materials": "file:src/plugins/packages/materials",
"@opentiny/tiny-engine-plugin-page": "file:src/plugins/packages/page",
"@opentiny/tiny-engine-plugin-schema": "file:src/plugins/packages/schema",
"@opentiny/tiny-engine-plugin-script": "file:src/plugins/packages/script",
"@opentiny/tiny-engine-plugin-tree": "file:src/plugins/packages/tree",
"@opentiny/tiny-engine-plugin-tutorial": "file:src/plugins/packages/tutorial",
"@opentiny/tiny-engine-plugin-robot": "file:src/plugins/packages/robot",
"@opentiny/tiny-engine-setting-design": "file:src/settings/packages/design",
"@opentiny/tiny-engine-setting-events": "file:src/settings/packages/events",
"@opentiny/tiny-engine-setting-props": "file:src/settings/packages/props",
"@opentiny/tiny-engine-setting-styles": "file:src/settings/packages/styles",
"@opentiny/tiny-engine-svgs": "file:src/svgs",
"@opentiny/tiny-engine-theme-dark": "file:src/theme/packages/dark",
"@opentiny/tiny-engine-theme-light": "file:src/theme/packages/light",
"@opentiny/tiny-engine-toolbar-breadcrumb": "file:src/toolbars/packages/breadcrumb",
"@opentiny/tiny-engine-toolbar-checkinout": "file:src/toolbars/packages/lock",
"@opentiny/tiny-engine-toolbar-clean": "file:src/toolbars/packages/clean",
"@opentiny/tiny-engine-toolbar-collaboration": "file:src/toolbars/packages/collaboration",
"@opentiny/tiny-engine-toolbar-fullscreen": "file:src/toolbars/packages/fullscreen",
"@opentiny/tiny-engine-toolbar-generate-vue": "file:src/toolbars/packages/generate-vue",
"@opentiny/tiny-engine-toolbar-lang": "file:src/toolbars/packages/lang",
"@opentiny/tiny-engine-toolbar-layout": "file:src/toolbars/packages/layout",
"@opentiny/tiny-engine-toolbar-logo": "file:src/toolbars/packages/logo",
"@opentiny/tiny-engine-toolbar-logout": "file:src/toolbars/packages/logout",
"@opentiny/tiny-engine-toolbar-media": "file:src/toolbars/packages/media",
"@opentiny/tiny-engine-toolbar-preview": "file:src/toolbars/packages/preview",
"@opentiny/tiny-engine-toolbar-redoundo": "file:src/toolbars/packages/redoundo",
"@opentiny/tiny-engine-toolbar-refresh": "file:src/toolbars/packages/refresh",
"@opentiny/tiny-engine-toolbar-save": "file:src/toolbars/packages/save",
"@opentiny/tiny-engine-toolbar-setting": "file:src/toolbars/packages/setting",
"@opentiny/tiny-engine-utils": "file:src/utils",
"@opentiny/tiny-engine-webcomponent-core": "file:src/webcomponent",
"@opentiny/tiny-engine-i18n-host": "file:src/i18n",
"@types/node": "^18.0.0",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^1.3.2",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"assert": "^2.0.0",
"buffer": "^6.0.3",
"chokidar": "^3.5.3",
"concurrently": "^8.2.0",
"cross-env": "^7.0.3",
"dotenv": "^16.3.1",
"eslint": "^8.38.0",
"eslint-plugin-vue": "^8.0.0",
"fast-glob": "^3.3.2",
"fs-extra": "^10.1.0",
"husky": "^8.0.0",
"lerna": "^5.1.8",
"lerna": "^7.2.0",
"less": "^4.1.2",
"lint-staged": "^13.2.0",
"mysql": "^2.18.1",
"path": "^0.12.7",
"picocolors": "^1.0.0",
"rimraf": "^3.0.2",
"rollup-plugin-polyfill-node": "^0.12.0",
"rollup-plugin-terser": "^7.0.2",
@ -120,11 +55,21 @@
"vite": "^4.3.7",
"vite-plugin-monaco-editor": "^1.0.10",
"vite-plugin-svg-icons": "^2.0.1",
"vue-eslint-parser": "^8.0.1"
"vue-eslint-parser": "^8.0.1",
"vue-i18n": "^9.9.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
],
"engines": {
"node": ">=14",
"pnpm": ">=7"
},
"pnpm": {
"patchedDependencies": {
"@vue/repl@2.9.0": "patches/@vue__repl@2.9.0.patch"
}
}
}

View File

@ -0,0 +1,12 @@
# @opentiny/tiny-engine-blockToWebComponentTemplate
将区块转换成 webComponent使得不同技术栈的区块可以统一在 vue 的画布上面运行
## 使用
- 后端拉取 template
- 将区块 schema 转换成 高代码,并写入 src 文件夹中
- 写入 lib.js替换 BlockFileName 为实际出码的文件名
- 执行 `pnpm install` 安装依赖
- 运行 `pnpm run build:block` 命令
- 得到 webcomponent 转换产物

View File

@ -0,0 +1,47 @@
{
"name": "@opentiny/tiny-engine-block-build",
"version": "1.0.2",
"description": "translate block to webcomponent template",
"main": "./dist/web-components.es.js",
"scripts": {
"build:block": "vite build --mode block"
},
"keywords": [
"vue",
"vue3",
"frontend",
"opentiny",
"lowcode",
"tiny-engine",
"webComponent"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
"directory": "packages/builtinComponent"
},
"bugs": {
"url": "https://github.com/opentiny/tiny-engine/issues"
},
"author": "OpenTiny Team",
"license": "MIT",
"homepage": "https://opentiny.design/tiny-engine",
"dependencies": {
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-webcomponent-core": "workspace:*",
"@opentiny/vue": "~3.14.0",
"@opentiny/vue-icon": "~3.14.0",
"@opentiny/vue-theme": "~3.14.0",
"@vue/shared": "^3.3.11",
"vue": "^3.4.15",
"vue-i18n": "^9.9.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.2",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"vite": "^4.3.7"
}
}

View File

@ -0,0 +1,46 @@
<template>
<div>
<tiny-popover class="block-link-field" popper-class="option-popper block-new-attr-popover">
<tiny-input placeholder="请输入字段名称"></tiny-input>
</tiny-popover>
<div>
<slot name="menu" :title="state.title">
<span>TinyEngine 前端可视化设计器为设计器开发者提供定制服务在线构建出自己专属的设计器</span>
</slot>
</div>
</div>
</template>
<script setup>
import * as vue from 'vue'
import { defineProps, defineEmits } from 'vue'
import { I18nInjectionKey } from 'vue-i18n'
import { Input as TinyInput, Popover as TinyPopover } from '@opentiny/vue'
const props = defineProps({ testSlot: { type: Object, default: () => ({}) } })
const emit = defineEmits([])
const { t, lowcodeWrap, stores } = vue.inject(I18nInjectionKey).lowcode()
const wrap = lowcodeWrap(props, { emit }, t)
const state = vue.reactive({
title: 'test slot params'
})
wrap({
stores,
state
})
</script>
<style scoped>
body {
background-color: #fff;
}
.test {
width: 100px;
padding: 10px;
margin: 10px;
color: #191919;
}
</style>

View File

@ -0,0 +1,20 @@
import { hyphenate } from '@vue/shared'
import { defineCustomElement } from '@opentiny/tiny-engine-webcomponent-core'
import block from './BlockFileName.vue'
window.TinyLowcodeResource = window.TinyLowcodeResource || {}
const blockName = hyphenate('BlockFileName')
if (customElements.get(blockName)) {
if (window.TinyLowcodeResource[blockName]) {
Object.assign(window.TinyLowcodeResource[blockName], block)
}
} else {
block.links = process.env.VUE_APP_UI_LIB_FULL_STYLE_FILE_URL
block.styles = ['svg { width: 10px; height: 10px;}', ...(block.styles || [])]
window.TinyLowcodeResource[blockName] = block
customElements.define(blockName, defineCustomElement(block))
}
export default block

View File

@ -0,0 +1,66 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import path from 'path'
const config = {
define: {},
resolve: {
alias: {}
},
build: {
cssCodeSplit: false,
minify: false,
commonjsOptions: {
transformMixedEsModules: true
},
rollupOptions: {
external: [
'vue',
'vue-i18n',
'@opentiny/tiny-engine-i18n-host',
'@opentiny/tiny-engine-webcomponent-core',
'@opentiny/vue',
'@opentiny/vue-icon'
],
output: {
globals: {
vue: 'Vue',
'vue-i18n': 'VueI18n',
'@opentiny/tiny-engine-i18n-host': 'TinyI18nHost',
'@opentiny/tiny-engine-webcomponent-core': 'TinyWebcomponentCore',
'@opentiny/vue': 'TinyVue',
'@opentiny/vue-icon': 'TinyVueIcon'
}
}
}
}
}
export default defineConfig(({ command, mode }) => {
if (command !== 'build' || mode !== 'block') {
return config
}
const vuePluginConfig = {}
const styleLinks = ['https://npm.onmicrosoft.cn/@opentiny/vue-theme@3.14/index.css']
config.publicDir = false
config.build.lib = {
entry: path.resolve(__dirname, './src/lib.js'),
name: 'TinyVueBlock',
formats: ['umd', 'es'],
fileName: (format) => `js/web-component.${format}.js`
}
vuePluginConfig.customElement = true
config.plugins = [vue(vuePluginConfig), vueJsx()]
config.define['process.env'] = {
VUE_APP_UI_LIB_FULL_STYLE_FILE_URL: styleLinks
}
return config
})

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) 2024 - present TinyEngine Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { transform } from './src/transform.js'
import { transformSFC } from './src/transform-sfc.js'
export default function () {
return {
name: 'vite-plugin-generate-comments',
enforce: 'pre',
transform(code, id) {
if (id.endsWith('.vue')) {
const result = transformSFC(code, id)
return result
}
if (id.endsWith('.js') || id.endsWith('.jsx') || id.endsWith('.ts')) {
const result = transform(code, id)
return result
}
}
}
}

View File

@ -0,0 +1,23 @@
{
"name": "@opentiny/vite-plugin-generate-comments",
"version": "1.0.0",
"description": "",
"main": "index.js",
"module": "index.js",
"type": "module",
"scripts": {
"test": "node ./src/test/index.js"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"vite": "^5.2.7",
"@babel/parser": "^7.18.13",
"@babel/traverse": "^7.18.13",
"@babel/generator": "^7.18.13",
"@babel/template": "^7.18.13",
"@vue/compiler-sfc": "^3.4.21"
},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@ -0,0 +1,57 @@
/* metaService */
/**
* Copyright (c) 2024 - present TinyEngine Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { reactive, onMounted, onBeforeMount as beforeMount } from 'vue'
import { deepCopy } from 'loash-es'
export const useRenderless = ({ props }) => {
const state = reactive({
tableData: props.data || props.op.data || []
})
onMounted(() => {})
onMounted(() => {})
onMounted(() => {})
beforeMount(() => {})
const logMessage = () => {
console.log('我是纯函数我不需要闭包参数')
}
const aaa = 'aaa',
bbb = 'bbb'
const handleClick = (e) => {
console.log(e.target, aaa)
state.tableData.push({
key: 'TinyEngine',
zhCN: '低代码引擎',
enUS: 'TinyEngine'
})
}
const ccc = 111
const sendMessage = () => {
logMessage('自定义是的范德萨')
}
function last() {}
return {
state,
aa,
handleClick,
sendMessage
}
}

View File

@ -0,0 +1,575 @@
import { callEntry as _callEntry, beforeCallEntry as _beforeCallEntry, afterCallEntry as _afterCallEntry, useCompile as _useCompile } from '@opentiny/tiny-engine-entry';
import _metaData from '../meta.js';
/* metaService */
import { reactive, onMounted, onBeforeMount as beforeMount } from 'vue';
import { deepCopy } from 'loash-es';
export const useRenderless = _callEntry(({
props
}) => {
const state = reactive({
tableData: props.data || props.op.data || []
});
onMounted(_callEntry(() => {}, {
metaData: {
id: `${_metaData.id}.onMounted[0]`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
}));
onMounted(_callEntry(() => {}, {
metaData: {
id: `${_metaData.id}.onMounted[1]`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
}));
onMounted(_callEntry(() => {}, {
metaData: {
id: `${_metaData.id}.onMounted[2]`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
}));
beforeMount(_callEntry(() => {}, {
metaData: {
id: `${_metaData.id}.onBeforeMount[0]`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
}));
_beforeCallEntry({
metaData: {
id: `${_metaData.id}.logMessage`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
const logMessage = _callEntry(() => {
console.log('我是纯函数我不需要闭包参数');
}, {
metaData: {
id: `${_metaData.id}.logMessage`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
_afterCallEntry({
metaData: {
id: `${_metaData.id}.logMessage`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
const aaa = 'aaa',
bbb = 'bbb';
_beforeCallEntry({
metaData: {
id: `${_metaData.id}.handleClick`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
e,
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
logMessage,
aaa,
bbb,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
const handleClick = _callEntry(e => {
console.log(e.target, aaa);
state.tableData.push({
key: 'TinyEngine',
zhCN: '低代码引擎',
enUS: 'TinyEngine'
});
}, {
metaData: {
id: `${_metaData.id}.handleClick`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
e,
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
logMessage,
aaa,
bbb,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
_afterCallEntry({
metaData: {
id: `${_metaData.id}.handleClick`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
e,
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
logMessage,
aaa,
bbb,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
const ccc = 111;
_beforeCallEntry({
metaData: {
id: `${_metaData.id}.sendMessage`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
const sendMessage = _callEntry(() => {
logMessage('自定义是的范德萨');
}, {
metaData: {
id: `${_metaData.id}.sendMessage`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
_afterCallEntry({
metaData: {
id: `${_metaData.id}.sendMessage`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
}
return asyncVars;
}
});
function last() {}
return {
state,
aa,
handleClick,
sendMessage
};
}, {
metaData: {
id: `${_metaData.id}.useRenderless`
},
ctx: () => {
let asyncVars = {};
try {
asyncVars = {
props,
state,
logMessage,
aaa,
bbb,
handleClick,
ccc,
sendMessage,
last,
reactive,
onMounted,
beforeMount,
deepCopy,
useRenderless
};
} catch (e) {
return {
reactive,
onMounted,
beforeMount,
deepCopy
};
}
return asyncVars;
}
});

View File

@ -0,0 +1,26 @@
/**
* Copyright (c) 2024 - present TinyEngine Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import fs from 'fs'
import { transform } from '../transform.js'
import { fileURLToPath } from 'node:url'
import * as path from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const code = fs.readFileSync(path.join(__dirname, './code/entry.js'), 'utf8')
const id = path.resolve(__dirname, './code/entry.js')
fs.writeFileSync(path.join(__dirname, './code/output.js'), transform(code, id) || '', 'utf8')

View File

@ -0,0 +1,62 @@
/**
* Copyright (c) 2024 - present TinyEngine Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { parse } from '@vue/compiler-sfc' //vue 处理sfc 的专用库
import { transform } from './transform.js'
import { isCallEntryFile } from './utils.js'
const getAttrsString = (attrs) => {
let attrStr = ''
if (!attrs) {
return attrStr
}
Object.keys(attrs).forEach((key) => {
const val = attrs[key]
if (val === true) {
attrStr += ` ${key}`
} else {
attrStr += ` ${key}="${val}"`
}
})
return attrStr
}
const generateTagContent = (tagDescriptor) => {
if (!tagDescriptor) {
return ''
}
const { attrs, content, type } = tagDescriptor
return `<${type}${getAttrsString(attrs)}>${content}</${type}>`
}
export const generateSFC = (descriptor) => {
const { script, scriptSetup, styles = [], template } = descriptor
return `${generateTagContent(template)}
${generateTagContent(script)}
${generateTagContent(scriptSetup)}
${styles.map(generateTagContent).join('\n')}
`
}
export const transformSFC = (code, id) => {
const { descriptor } = parse(code)
const { script, scriptSetup } = descriptor
if (!isCallEntryFile(code) || (!script && !scriptSetup)) {
return
}
if (script) {
script.content = transform(script.content, id) || script.content
}
if (scriptSetup) {
scriptSetup.content = transform(scriptSetup.content, id) || scriptSetup.content
}
return generateSFC(descriptor)
}

View File

@ -0,0 +1,179 @@
/**
* Copyright (c) 2024 - present TinyEngine Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { parse } from '@babel/parser'
import generate from '@babel/generator'
import traverse from '@babel/traverse'
import template from '@babel/template'
import {
wrapEntryFuncNode,
COMMON_PACKAGE_NAME,
CALLENTRY,
BEFORE_CALLENTRY,
AFTER_CALLENTRY,
USE_COMPILE,
METADATANAME,
isCallEntryFile,
isCompileFile,
getMeataPath,
wrapExportComp,
vueLifeHook,
wrapHookCall,
getModuleId
} from './utils.js'
const generateTraverse = traverse.default
export const transform = (code, id) => {
// 如果不包含metaService或者metaComponent的文件直接退出
const isCallEntry = isCallEntryFile(code)
const isCompile = isCompileFile(code)
if (!isCallEntry && !isCompile) {
return
}
// 本次转换保存的状态
const state = {
varName: {}, // 变量名对应的映射表
hooksName: {},
hooksIndex: {},
varDeclartion: new Map(),
moduleId: '', // 自定义的模块ID用于区分元服务中不同文件,
noUseVars: []
}
// 找不到meta.js告警并返回
const metaPath = getMeataPath(id)
if (!metaPath) {
console.log('找不到对应的meta.js')
return
}
// 将源码解析为ast语法数
const resultAst = parse(code, {
sourceType: 'module',
plugins: ['typescript', 'jsx']
})
generateTraverse(resultAst, {
// 使用特定的类型回调处理、函数表达式、箭头函数、带导出的函数
'ArrowFunctionExpression|FunctionExpression'(path) {
const parentNode = path.parentPath || {}
const functionName = parentNode.node?.id?.name
// 只有拿到函数的名称才可以被复写
if (functionName) {
wrapEntryFuncNode({
path,
functionName,
varName: state.varName,
state
})
}
},
ImportDeclaration(path) {
// 解析vue的引入
const depName = path.node?.source?.value
if (depName === 'vue') {
const specifiers = path.node.specifiers
specifiers?.forEach((importSpecifier) => {
const { imported, local } = importSpecifier
const hookName = vueLifeHook.find((name) => imported.name === name)
if (hookName) {
state.hooksName[local.name] = hookName
}
state.noUseVars.push(local.name)
})
} else if (depName === '@opentiny/vue') {
const specifiers = path.node.specifiers
specifiers?.forEach((importSpecifier) => {
const { local } = importSpecifier
state.noUseVars.push(local.name)
})
}
},
VariableDeclaration(path) {
path.node.declarations?.forEach((val) => {
const name = val.id.name
const block = path.scope.block
if (!state.varDeclartion.has(block)) {
const arr = [name]
state.varDeclartion.set(block, arr)
} else {
const arr = state.varDeclartion.get(block)
arr.push(name)
}
})
},
ExpressionStatement(path) {
const { hooksName, varName, hooksIndex } = state
const callName = path.node.expression?.callee?.name
const hookName = hooksName[callName]
if (hookName) {
let hookIndex
if (hooksIndex[hookName]) {
hookIndex = hooksIndex[hookName]
hooksIndex[hookName] = hookIndex + 1
} else {
hooksIndex[hookName] = 1
hookIndex = 0
}
const functionName = `${hookName}[${hookIndex}]`
wrapHookCall({
path,
varName,
hooksName,
functionName,
callName,
state
})
}
},
Program(path) {
const code = path.toString()
state.moduleId = getModuleId(code)
const metaData = path.scope.generateUid(METADATANAME)
state.varName[METADATANAME] = metaData
path.node.body.unshift(template.statement(`import ${metaData} from '${metaPath}'`)())
const callEntry = path.scope.generateUid(CALLENTRY)
const beforeCallEntry = path.scope.generateUid(BEFORE_CALLENTRY)
const afterCallEntry = path.scope.generateUid(AFTER_CALLENTRY)
const useCompile = path.scope.generateUid(USE_COMPILE)
state.varName[CALLENTRY] = callEntry
state.varName[BEFORE_CALLENTRY] = beforeCallEntry
state.varName[AFTER_CALLENTRY] = afterCallEntry
state.varName[USE_COMPILE] = useCompile
path.node.body.unshift(
template.statement(
`import {
${CALLENTRY} as ${callEntry},
${BEFORE_CALLENTRY} as ${beforeCallEntry},
${AFTER_CALLENTRY} as ${afterCallEntry},
${USE_COMPILE} as ${useCompile}
} from '${COMMON_PACKAGE_NAME}'`
)()
)
},
ExportDefaultDeclaration(path) {
const comment = path.node.leadingComments
const lastComment = comment && comment[comment.length - 1].value
// 只判断最接近export default的注释节点
if (comment && lastComment.includes('metaComponent')) {
wrapExportComp({ path, varName: state.varName })
path.skip()
}
}
})
return generate.default(resultAst).code || ''
}

View File

@ -0,0 +1,246 @@
/**
* Copyright (c) 2024 - present TinyEngine Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import template from '@babel/template'
import path from 'node:path'
import fs from 'node:fs'
export const CALLENTRY = 'callEntry'
export const BEFORE_CALLENTRY = 'beforeCallEntry'
export const AFTER_CALLENTRY = 'afterCallEntry'
export const USE_COMPILE = 'useCompile'
export const METADATANAME = 'metaData'
export const COMMON_PACKAGE_NAME = '@opentiny/tiny-engine-entry'
export const vueLifeHook = [
'onMounted',
'onUpdated',
'onUnmounted',
'onBeforeMount',
'onBeforeUpdate',
'onBeforeUnmount',
'onActivated',
'onDeactivated'
]
const callEntryExp = /\/\*\s*metaService/
const compileExp = /\/\*\s*metaComponent/
export const isCallEntryFile = (code) => {
return callEntryExp.test(code)
}
export const isCompileFile = (code) => {
return compileExp.test(code)
}
export const getModuleId = (str) => {
const [, moduleId = ''] = str.match(/\/\*\s*metaService: \s*(.+?)\s*\*\//) || []
return moduleId
}
// 将注释中的参数提取出来,并组合成目前参数格式
export const getEntryParam = ({ functionName = '', syncVars, asyncVars, state }) => {
const { varName, moduleId, noUseVars } = state
const metaData = varName[METADATANAME]
const id = moduleId ? `'${moduleId}.${functionName}'` : `\`\${${metaData}.id}.${functionName}\``
const syncVarsKey = Object.keys(syncVars).filter((key) => !noUseVars.includes(key))
const asyncVarsKey = Object.keys(asyncVars).filter((key) => !noUseVars.includes(key) && !syncVarsKey.includes(key))
const ctx = ` () => {
let asyncVars = {}
const syncVars = {${syncVarsKey.join(',')}}
try {
asyncVars = { ${asyncVarsKey.join(',')} }
} catch {
return syncVars
}
return { ...syncVars, ...asyncVars }
}`
if (functionName) {
return `{ ${METADATANAME}: { id: ${id} }, ctx: ${ctx}}`
}
return `{ ${METADATANAME}: ${metaData} }`
}
const getParentVariableDeclaration = (path) => {
if (!path) {
return
}
if (path.type === 'VariableDeclaration' && path.parentPath.type !== 'ExportNamedDeclaration') {
return path
} else {
return getParentVariableDeclaration(path?.parentPath)
}
}
const generateBeforeAfterEntry = ({ path, beforeEntryAst, afterEntryAst }) => {
const parent = getParentVariableDeclaration(path)
if (parent) {
parent.insertBefore(beforeEntryAst)
parent.insertAfter(afterEntryAst)
}
}
export const getOuterBingdings = (path) => {
const outerBindings = {}
const allBindings = path.scope.getAllBindings()
const selfBindings = path.scope.bindings
Object.keys(allBindings).forEach((key) => {
if (allBindings[key] && !selfBindings[key]) {
outerBindings[key] = allBindings[key]
}
})
return outerBindings
}
// 获取当前上下文已经可以使用的scope变量
export const getValidBingdinngs = ({ path, state, functionName }) => {
const validBindings = {}
const { varDeclartion } = state
let varArr = []
let parentPath = path.parentPath
let block
while (parentPath) {
const newBlock = parentPath.scope.block
parentPath = parentPath.parentPath
if (newBlock === block) {
continue
}
block = newBlock
varArr = varArr.concat(varDeclartion.get(block))
}
const allBindings = path.scope.getAllBindings()
const selfBindings = path.scope.bindings
Object.keys(allBindings).forEach((key) => {
if (selfBindings[key]) {
return
}
const value = allBindings[key]
// 如果是变量定义,并且此时还没有初始化,则过滤掉
if ((['var', 'const', 'let'].includes(value.kind) && !varArr.includes(key)) || key === functionName) {
return
}
validBindings[key] = value
})
return validBindings
}
export const getModuleBindings = (path) => {
const moduleBindings = {}
const allBindings = path.scope.getAllBindings()
Object.keys(allBindings).forEach((key) => {
if (allBindings[key].kind === 'module') {
moduleBindings[key] = allBindings[key]
}
})
return moduleBindings
}
// 生成callEntry表达式并包裹当前函数如果有参与还需要处理参数
export const wrapEntryFuncNode = ({ path, functionName = '', varName, state }) => {
const syncVars = getValidBingdinngs({ path, state, functionName })
const asyncVars = getOuterBingdings(path)
const entryParam = getEntryParam({
functionName,
syncVars,
asyncVars,
varName,
state
})
const callEntry = varName[CALLENTRY]
const beforeCallEntry = varName[BEFORE_CALLENTRY]
const afterCallEntry = varName[AFTER_CALLENTRY]
const entryAst = template.statement(`${callEntry}(${entryParam})`)()
const beforeEntryAst = template.statement(`${beforeCallEntry}(${entryParam})`)()
const afterEntryAst = template.statement(`${afterCallEntry}(${entryParam})`)()
const resultNode = path.node
generateBeforeAfterEntry({ path, beforeEntryAst, afterEntryAst })
entryAst.expression.arguments.unshift(JSON.parse(JSON.stringify(resultNode)))
// 替换整个节点
path.replaceWith(entryAst)
}
// 获取两个文件路径的相对路径,入参为两个文件绝对路径
export const getRelFilePath = (path1, path2) => {
const dir1 = path.join(path1, '..')
const dir2 = path.join(path2, '..')
const relPath = path.relative(dir1, dir2) || '.'
return `${relPath}/${path.basename(path2)}`.replaceAll('\\', '/')
}
// 向上获取meta.js的相对路径
export const getMeataPath = (id) => {
let tempPath = path.join(id, '../meta.js')
const endCondition = () => {
// 找到了meta.js
const findMeta = fs.existsSync(tempPath)
// 发现了package.json说明到达子包根目录
const isSubRoot = fs.existsSync(path.join(tempPath, '../package.json'))
// 到达系统根节点,防止死循环
const isRoot = tempPath === path.join(tempPath, '../../meta.js')
return findMeta || isSubRoot || isRoot
}
while (!endCondition()) {
tempPath = path.join(tempPath, '../../meta.js')
}
if (fs.existsSync(tempPath)) {
return getRelFilePath(id, tempPath)
}
return null
}
export const wrapExportComp = ({ path, varName }) => {
const properties = path.node.declaration?.properties || []
const metaData = varName[METADATANAME]
const useCompile = varName[USE_COMPILE]
// 对键值为component属性包一层useCompile
properties.forEach((prop) => {
if (prop.key?.name === 'component') {
const val = prop.value
const compileAst = template.statement(`${useCompile}({ component: null, ${METADATANAME}: ${metaData} });`)()
compileAst.expression.arguments[0].properties[0].value = val
path.traverse({
enter(subPath) {
if (subPath.node === val) {
subPath.replaceWith(compileAst)
subPath.skip()
}
}
})
}
})
}
export const wrapHookCall = ({ path, varName, functionName, callName, state }) => {
// vue的生命周期hook只有一个参数
const argument = path.node.expression.arguments[0]
const callEntry = varName[CALLENTRY]
const syncVars = getValidBingdinngs({ path, state, functionName })
const asyncVars = path.scope.getAllBindings()
const entryParam = getEntryParam({
functionName,
syncVars,
asyncVars,
varName,
state
})
const wrapAst = template.statement(`${callName}(${callEntry}(${entryParam}))`)()
wrapAst.expression.arguments[0].arguments.unshift(argument)
path.replaceWith(wrapAst)
path.skip()
}

View File

@ -0,0 +1,9 @@
# 内置组件
## 目前内置的组件
### CanvasRow
### CanvasCol
### CanvasRowColContainer

View File

@ -0,0 +1,4 @@
export { default as CanvasCol } from './src/components/CanvasCol.vue'
export { default as CanvasRow } from './src/components/CanvasRow.vue'
export { default as CanvasRowColContainer } from './src/components/CanvasRowColContainer.vue'
export { default as meta } from './src/meta'

View File

@ -0,0 +1,33 @@
{
"name": "@opentiny/tiny-engine-builtin-component",
"version": "1.0.1",
"description": "",
"main": "dist/index.js",
"module": "dist/index.js",
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
"directory": "packages/builtinComponent"
},
"scripts": {
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vite-plugin-css-injected-by-js": "^3.3.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"vite": "^4.5.0"
},
"peerDependencies": {
"vue": "^3.4.15"
}
}

View File

@ -0,0 +1,76 @@
<template>
<div ref="colRef" class="canvas-col">
<slot></slot>
</div>
</template>
<script setup>
import { computed, defineProps } from 'vue'
import { getStyleValue, alignMap, justAlignMap } from './helper'
const props = defineProps({
flexBasis: {
type: String,
default: '0px'
},
rowGap: {
type: [String, Number],
default: ''
},
colGap: {
type: [String, Number],
default: ''
},
align: {
type: [String, Number],
default: ''
},
justAlign: {
type: [String, Number],
default: ''
},
grow: {
type: Boolean,
default: true
},
shrink: {
type: Boolean,
default: true
},
widthType: {
type: String,
default: 'auto'
}
})
const getFlex = () => {
const { flexBasis, grow, shrink, widthType } = props
if (widthType === 'fixed') {
return `0 0 ${getStyleValue(flexBasis)}`
}
return `${Number(grow)} ${Number(shrink)} ${getStyleValue(flexBasis)}`
}
const styles = computed(() => ({
flex: getFlex(props.flexBasis),
rowGap: getStyleValue(props.rowGap),
colGap: getStyleValue(props.colGap),
align: alignMap[props.align] || 'stretch',
justAlign: justAlignMap[props.justAlign] || 'flex-start'
}))
</script>
<style lang="less" scoped>
.canvas-col {
display: flex;
flex: v-bind('styles.flex');
flex-direction: column;
flex-wrap: nowrap;
row-gap: v-bind('styles.rowGap');
column-gap: v-bind('styles.colGap');
align-items: v-bind('styles.align');
justify-content: v-bind('styles.justAlign');
}
</style>

View File

@ -0,0 +1,54 @@
<template>
<div class="canvas-row">
<slot></slot>
</div>
</template>
<script setup>
import { computed, defineProps } from 'vue'
import { getStyleValue, alignMap, justAlignMap } from './helper'
const props = defineProps({
minHeight: {
type: [String, Number],
default: ''
},
rowGap: {
type: [String, Number],
default: ''
},
colGap: {
type: [String, Number],
default: ''
},
align: {
type: [String, Number],
default: ''
},
justAlign: {
type: [String, Number],
default: ''
}
})
const styles = computed(() => ({
minHeight: getStyleValue(props.minHeight),
rowGap: getStyleValue(props.rowGap),
colGap: getStyleValue(props.colGap),
align: alignMap[props.align] || 'stretch',
justAlign: justAlignMap[props.justAlign] || 'flex-start'
}))
</script>
<style lang="less" scoped>
.canvas-row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: v-bind('styles.justAlign');
align-items: v-bind('styles.align');
column-gap: v-bind('styles.rowGap');
row-gap: v-bind('styles.colGap');
min-height: v-bind('styles.minHeight');
}
</style>

View File

@ -0,0 +1,29 @@
<template>
<div class="row-col-container">
<slot> </slot>
</div>
</template>
<script setup>
import { computed, defineProps } from 'vue'
import { getStyleValue } from './helper'
const props = defineProps({
rowGap: {
type: [String, Number],
default: ''
}
})
const styles = computed(() => ({
rowGap: getStyleValue(props.rowGap)
}))
</script>
<style lang="less" scoped>
.row-col-container {
display: flex;
flex-direction: column;
row-gap: v-bind('styles.rowGap');
}
</style>

View File

@ -0,0 +1,46 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
export const getStyleValue = (value) => {
if (typeof value === 'number' || /^\d+\.?\d*$/.test(value)) {
return `${value}px`
}
if (/^\d+\.?\d*(px|%|pt|em|rem|vw|vh)$/.test(value)) {
return value
}
return ''
}
export const alignMap = {
'flex-start': 'flex-start',
'flex-end': 'flex-end',
center: 'center',
stretch: 'stretch',
start: 'start',
end: 'end'
}
export const justAlignMap = {
'space-between': 'space-between',
'space-around': 'space-around',
'space-evenly': 'space-evenly',
'flex-start': 'flex-start',
'flex-end': 'flex-end',
stretch: 'stretch',
center: 'center',
start: 'start',
end: 'end',
left: 'left',
right: 'right'
}

View File

@ -0,0 +1,196 @@
{
"components": {
"icon": "Box",
"name": {
"zh_CN": "CanvasCol"
},
"component": "CanvasCol",
"schema": {
"slots": {},
"properties": [
{
"label": {
"zh_CN": "基础信息"
},
"description": {
"zh_CN": "基础信息"
},
"collapse": {
"number": 6,
"text": {
"zh_CN": "显示更多"
}
},
"content": [
{
"property": "widthType",
"type": "String",
"defaultValue": "auto",
"label": {
"text": {
"zh_CN": "宽度类型"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaRadioGroup",
"props": {
"options": [
{ "label": "auto", "text": "自适应" },
{ "label": "fixed", "text": "固定" }
],
"type": "button"
}
}
},
{
"property": "flexBasis",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "固定宽度"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
},
{
"property": "rowGap",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "行间距"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
},
{
"property": "colGap",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "列间距"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
},
{
"property": "align",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "副轴对齐"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaSelect",
"props": {
"options": [
{ "value": "flex-start", "label": "头部对齐" },
{ "value": "center", "label": "中间对齐" },
{ "value": "flex-end", "label": "尾端对齐" },
{ "value": "stretch", "label": "拉伸对齐" }
],
"type": "button"
}
}
},
{
"property": "justAlign",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "主轴对齐"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaSelect",
"props": {
"options": [
{ "value": "flex-start", "label": "头部对齐" },
{ "value": "center", "label": "中间对齐" },
{ "value": "flex-end", "label": "尾端对齐" },
{ "value": "space-between", "label": "两端对齐" },
{ "value": "space-evenly", "label": "均分对齐" }
],
"type": "button"
}
}
},
{
"property": "grow",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "增长"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaSwitch",
"props": {}
}
},
{
"property": "shrink",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "收缩"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaSwitch",
"props": {}
}
}
]
}
],
"events": {},
"shortcuts": {
"properties": []
},
"contentMenu": {
"actions": []
}
},
"configure": {
"loop": true,
"isContainer": true,
"nestingRule": {
"childWhitelist": [],
"descendantBlacklist": []
}
}
}
}

View File

@ -0,0 +1,142 @@
{
"components": {
"icon": "Box",
"name": {
"zh_CN": "CanvasRow"
},
"component": "CanvasRow",
"schema": {
"slots": {},
"properties": [
{
"label": {
"zh_CN": "基础信息"
},
"description": {
"zh_CN": "基础信息"
},
"collapse": {
"number": 6,
"text": {
"zh_CN": "显示更多"
}
},
"content": [
{
"property": "minHeight",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "最小高度"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
},
{
"property": "rowGap",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "行间距"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
},
{
"property": "colGap",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "列间距"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
},
{
"property": "align",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "副轴对齐"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaSelect",
"props": {
"options": [
{ "value": "flex-start", "label": "头部对齐" },
{ "value": "center", "label": "中间对齐" },
{ "value": "flex-end", "label": "尾端对齐" },
{ "value": "stretch", "label": "拉伸对齐" }
],
"type": "button"
}
}
},
{
"property": "justAlign",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "主轴对齐"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaSelect",
"props": {
"options": [
{ "value": "flex-start", "label": "头部对齐" },
{ "value": "center", "label": "中间对齐" },
{ "value": "flex-end", "label": "尾端对齐" },
{ "value": "space-between", "label": "两端对齐" },
{ "value": "space-evenly", "label": "均分对齐" }
],
"type": "button"
}
}
}
]
}
],
"events": {},
"shortcuts": {
"properties": []
},
"contentMenu": {
"actions": []
}
},
"configure": {
"loop": true,
"isContainer": true,
"nestingRule": {
"childWhitelist": [],
"descendantBlacklist": []
}
}
}
}

View File

@ -0,0 +1,96 @@
{
"components": {
"icon": "Box",
"name": {
"zh_CN": "行列容器"
},
"component": "CanvasRowColContainer",
"schema": {
"slots": {},
"properties": [
{
"label": {
"zh_CN": "基础信息"
},
"description": {
"zh_CN": "基础信息"
},
"collapse": {
"number": 6,
"text": {
"zh_CN": "显示更多"
}
},
"content": [
{
"property": "rowGap",
"type": "String",
"defaultValue": "",
"label": {
"text": {
"zh_CN": "行间距"
}
},
"cols": 12,
"rules": [],
"widget": {
"component": "MetaInput",
"props": {}
}
}
]
}
],
"events": {},
"shortcuts": {
"properties": []
},
"contentMenu": {
"actions": []
}
},
"configure": {
"loop": true,
"isContainer": true,
"nestingRule": {
"childWhitelist": [],
"descendantBlacklist": []
}
}
},
"snippets": {
"name": {
"zh_CN": "行列容器"
},
"screenshot": "",
"snippetName": "CanvasRowColContainer",
"icon": "Box",
"schema": {
"componentName": "CanvasRowColContainer",
"props": {
"rowGap": "20px"
},
"children": [
{
"componentName": "CanvasRow",
"props": {
"rowGap": "20px",
"colGap": "20px"
},
"children": [
{
"componentName": "CanvasCol",
"props": {
"rowGap": "20px",
"colGap": "20px",
"grow": true,
"shrink": true,
"widthType": "auto"
}
}
]
}
]
}
}
}

View File

@ -0,0 +1,18 @@
import CanvasCol from './CanvasCol.json'
import CanvasRow from './CanvasRow.json'
import CanvasRowColContainer from './CanvasRowColContainer.json'
export default {
components: [
{
group: '内置组件',
children: [{ ...CanvasCol.components }, { ...CanvasRow.components }, { ...CanvasRowColContainer.components }]
}
],
snippets: [
{
group: '内置组件',
children: [{ ...CanvasRowColContainer.snippets }]
}
]
}

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { defineConfig } from 'vite'
import path from 'path'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vitePluginCssInjectedByJs from 'vite-plugin-css-injected-by-js'
export default defineConfig({
plugins: [vue(), vueJsx(), vitePluginCssInjectedByJs()],
publicDir: false,
build: {
cssCodeSplit: false,
lib: {
entry: path.resolve(__dirname, './index.js'),
name: 'builtinComponent',
fileName: () => 'index.js',
formats: ['es']
},
rollupOptions: {
external: ['vue']
}
}
})

View File

@ -0,0 +1,52 @@
{
"name": "@opentiny/tiny-engine-canvas",
"version": "1.0.3",
"publishConfig": {
"access": "public"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"main": "dist/index.js",
"module": "dist/index.js",
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
"directory": "packages/canvas"
},
"bugs": {
"url": "https://github.com/opentiny/tiny-engine/issues"
},
"author": "OpenTiny Team",
"license": "MIT",
"homepage": "https://opentiny.design/tiny-engine",
"dependencies": {
"@babel/core": "7.18.13",
"@opentiny/tiny-engine-builtin-component": "workspace:*",
"@opentiny/tiny-engine-controller": "workspace:*",
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"@opentiny/tiny-engine-webcomponent-core": "workspace:*",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/shared": "^3.3.4",
"@vueuse/core": "^9.6.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"rollup-plugin-terser": "^7.0.2",
"vite": "^4.3.7"
},
"peerDependencies": {
"@opentiny/vue": "^3.14.0",
"@opentiny/vue-icon": "^3.14.0",
"@opentiny/vue-renderless": "^3.14.0",
"vue": "^3.4.15",
"vue-i18n": "^9.9.0"
}
}

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Some files were not shown because too many files have changed in this diff Show More