Merge remote-tracking branch 'origin/main'

This commit is contained in:
Chareice 2022-04-27 21:02:21 +08:00
commit 147b364d41
55 changed files with 366 additions and 257 deletions

View File

@ -10,6 +10,7 @@ SERVER_BASE_PATH=/api/
SERVER_BASE_URL=
DB_DIALECT=sqlite
DB_STORAGE=db.sqlite
# DB_HOST=localhost
# DB_PORT=5432

View File

@ -1,4 +1,4 @@
English | [简体中文](./README.zh-CN.md)
English | [中文](./README.zh-CN.md)
![](https://nocobase.oss-cn-beijing.aliyuncs.com/bbcedd403d31cd1ccc4e9709581f5c2f.png)
@ -15,42 +15,32 @@ https://demo.nocobase.com/new
Contact Us:
hello@nocobase.com
When to use NocoBase
----------
- **SMEs and organizations build business platforms and management systems for themselves or for their industry**
- Want the price to be low enough or even free
- Can be flexibly customized without programming knowledge
- Need full control of source code and data
- Can freely distribute and sell as their own products
- **Service providers and outsourcing teams develop collaboration platforms and management systems for their clients**
- Want to keep development costs as low as possible
- Need the most user-friendly secondary development experience
- Must be deployed privately as a standalone product for the client
- Can be freely distributed and sold by the client
Why choose NocoBase
----------
- **Open source and free**
- Unrestricted commercial use under the MIT license
- Unrestricted commercial use under the Apache-2.0 license
- Full code ownership, private deployment, private and secure data
- Free to expand and develop for actual needs
- Good ecological support
- **Strong no-code capability**
- WYSIWYG visual configuration
- Separation of data structure configuration from interface configuration
- Rich combination of blocks and operations
- Role-based access control
- Data Model
- Dozens of field types such as text, attachments, etc., as well as many-to-many, one-to-many, one-to-one relationships.
- Menu
- Groups, pages, links combination into menu, support infinite level submenu
- Block
- Rich block types such as tables, kanban, calendars, forms, etc. are freely combined within the page to display and manipulate data.
- Action
- Configure actions such as filtering, exporting, adding, deleting, modifying, and viewing to process data.
- ACL
- Role-based control of user's system configuration rights, action rights and menu access rights.
- Workflow
- Repetitive tasks are replaced by automation, reducing manual operations and increasing efficiency.
- **Developer-friendly**
- Microkernel architecture, flexible and easy to extend, with a robust plug-in system
- Node.js-based, with popular frameworks and technologies, including Koa, Sequelize, React, Formily, Ant Design, etc.
- Progressive development, easy for getting-started, friendly to newcomers
- No binding, no strong dependencies, can be used in any combination or extensions, can be used in existing projects
Note
----------
NocoBase is still in early development and is for preview purposes only and is not suitable for use in a production environment. A relatively stable and well-documented public beta is expected to be released as early as the first quarter of 2022.
If you are interested in NocoBase, please join us to discuss and develop it together.
Architecture
----------

View File

@ -11,23 +11,10 @@ NocoBase 是一个极易扩展的开源无代码开发平台。
在线体验https://demo-cn.nocobase.com/new
哪些场景适合使用 NocoBase
----------
- 中小企业和组织为自己或者为所在行业搭建业务平台和管理系统
- 希望价格足够低,甚至免费
- 不懂编程也可以灵活定制
- 需要完全掌控源代码和数据
- 可以以自有产品的形态自由分发和销售
- 服务商和外包团队为客户开发协作平台和管理系统
- 希望尽可能降低开发成本
- 需要极致友好的二次开发体验
- 必须以独立产品的形态为客户私有部署
- 客户可以自由分发和销售
为什么选择 NocoBase
----------
- 开源免费
- 采用 MIT 许可协议,不限制商业使用
- 采用 Apache-2.0 许可协议,不限制商业使用
- 拥有全部代码,私有化部署,保障数据私有和安全
- 针对实际需求自由扩展开发
- 具备良好的生态支持
@ -44,7 +31,6 @@ NocoBase 是一个极易扩展的开源无代码开发平台。
说明
----------
NocoBase 仍处于早期开发阶段,功能不完整,稳定性不高,仅用于预览,不适合在生产环境中使用。相对稳定以及包含完善文档的公开测试版预计最早将于 2022 年第一季度发布。
如果你希望加入我们一起开发 NocoBase或者探讨 NocoBase 未来发展,或者需要提供 NocoBase 使用上的帮助欢迎通过邮件联系我们hello@nocobase.com
@ -98,6 +84,10 @@ yarn create nocobase-app my-nocobase-app -d postgres \
# 2. 切换目录
cd my-nocobase-app
# 📢 由于网络环境、系统配置等因素影响,接下来这一步骤可能需要十几分钟时间
# 📢 使用 SQLite 数据库时,需要配置 sqlite3_binary_host_mirror
yarn config set sqlite3_binary_host_mirror https://npmmirror.com/mirrors/sqlite3/
# 3. 安装依赖(使用阿里云镜像)
yarn install --registry=https://registry.npmmirror.com

View File

@ -1,5 +1,5 @@
{
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"npmClient": "yarn",
"useWorkspaces": true,
"npmClientArgs": [

View File

@ -15,7 +15,7 @@
],
"scripts": {
"start": "concurrently --kill-others \"npm run start-server\" \"npm run start-client\"",
"start-pm2": "yarn pm2-runtime start packages/app/server/lib/index.js",
"start-pm2": "pm2-runtime start --node-args=\"-r dotenv/config\" packages/app/server/lib/index.js -- start",
"start-docs": "dumi dev",
"bootstrap": "lerna bootstrap",
"clean": "rimraf -rf packages/{app,core,plugins}/*/{lib,esm,dist} && lerna clean",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/app-client",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"license": "MIT",
"scripts": {
"start": "umi dev",
@ -10,7 +10,7 @@
"test:coverage": "umi-test --coverage"
},
"devDependencies": {
"@nocobase/client": "0.7.0-alpha.10",
"@nocobase/client": "0.7.0-alpha.15",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@umijs/test": "^3.5.20",

View File

@ -7,6 +7,29 @@
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
<link rel="manifest" href="/favicon/site.webmanifest">
<style>
/* width */
.win ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/* Track */
.win ::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
.win ::-webkit-scrollbar-thumb {
background: #c0c0c0;
border-radius: 4px;
}
/* Handle on hover */
.win ::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
.win .rc-virtual-list-scrollbar-thumb {
background: #c0c0c0 !important;
}
</style>
<script>
showLog=true;function log(m){if(window.console&&showLog){console.log(m)}}function css_browser_selector(u){var uaInfo={},screens=[320,480,640,768,1024,1152,1280,1440,1680,1920,2560],allScreens=screens.length,ua=u.toLowerCase(),is=function(t){return RegExp(t,'i').test(ua)},version=function(p,n){n=n.replace('.','_');var i=n.indexOf('_'),ver='';while(i>0){ver+=' '+p+n.substring(0,i);i=n.indexOf('_',i+1)}ver+=' '+p+n;return ver},g='gecko',w='webkit',c='chrome',f='firefox',s='safari',o='opera',m='mobile',a='android',bb='blackberry',lang='lang_',dv='device_',html=document.documentElement,b=[(!/opera|webtv/i.test(ua)&&/msie\s(\d+)/.test(ua))||/trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.test(ua)?'ie ie'+(/trident\/4\.0/.test(ua)?'8':RegExp.$1=='11.0'?'11':RegExp.$1):is('firefox/')?g+' '+f+(/firefox\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+f+RegExp.$2+' '+f+RegExp.$2+'_'+RegExp.$4:''):is('gecko/')?g:is('opera')?o+(/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+o+RegExp.$2+' '+o+RegExp.$2+'_'+RegExp.$4:/opera(\s|\/)(\d+)\.(\d+)/.test(ua)?' '+o+RegExp.$2+' '+o+RegExp.$2+'_'+RegExp.$3:''):is('konqueror')?'konqueror':is('blackberry')?bb+(/Version\/(\d+)(\.(\d+)+)/i.test(ua)?' '+bb+RegExp.$1+' '+bb+RegExp.$1+RegExp.$2.replace('.','_'):/Blackberry ?(([0-9]+)([a-z]?))[\/|;]/gi.test(ua)?' '+bb+RegExp.$2+(RegExp.$3?' '+bb+RegExp.$2+RegExp.$3:''):''):is('android')?a+(/Version\/(\d+)(\.(\d+))+/i.test(ua)?' '+a+RegExp.$1+' '+a+RegExp.$1+RegExp.$2.replace('.','_'):'')+(/Android (.+); (.+) Build/i.test(ua)?' '+dv+RegExp.$2.replace(/ /g,'_').replace(/-/g,'_'):''):is('chrome')?w+' '+c+(/chrome\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+c+RegExp.$2+(RegExp.$4>0?' '+c+RegExp.$2+'_'+RegExp.$4:''):''):is('iron')?w+' iron':is('applewebkit/')?w+' '+s+(/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+s+RegExp.$2+' '+s+RegExp.$2+RegExp.$3.replace('.','_'):/ Safari\/(\d+)/i.test(ua)?RegExp.$1=='419'||RegExp.$1=='417'||RegExp.$1=='416'||RegExp.$1=='412'?' '+s+'2_0':RegExp.$1=='312'?' '+s+'1_3':RegExp.$1=='125'?' '+s+'1_2':RegExp.$1=='85'?' '+s+'1_0':'':''):is('mozilla/')?g:'',is('android|mobi|mobile|j2me|iphone|ipod|ipad|blackberry|playbook|kindle|silk',)?m:'',is('j2me')?'j2me':is('ipad|ipod|iphone')?(/CPU( iPhone)? OS (\d+[_|\.]\d+([_|\.]\d+)*)/i.test(ua)?'ios'+version('ios',RegExp.$2):'')+' '+(/(ip(ad|od|hone))/gi.test(ua)?RegExp.$1:''):is('playbook')?'playbook':is('kindle|silk')?'kindle':is('playbook')?'playbook':is('mac')?'mac'+(/mac os x ((\d+)[.|_](\d+))/.test(ua)?' mac'+RegExp.$2+' mac'+RegExp.$1.replace('.','_'):''):is('win')?'win'+(is('windows nt 6.2')?' win8':is('windows nt 6.1')?' win7':is('windows nt 6.0')?' vista':is('windows nt 5.2')||is('windows nt 5.1')?' win_xp':is('windows nt 5.0')?' win_2k':is('windows nt 4.0')||is('WinNT4.0')?' win_nt':''):is('freebsd')?'freebsd':is('x11|linux')?'linux':'',/[; |\[](([a-z]{2})(\-[a-z]{2})?)[)|;|\]]/i.test(ua)?(lang+RegExp.$2).replace('-','_')+(RegExp.$3!=''?(' '+lang+RegExp.$1).replace('-','_'):''):'',is('ipad|iphone|ipod')&&!is('safari')?'ipad_app':'',];console.debug(ua);function screenSize(){var w=window.outerWidth||html.clientWidth;var h=window.outerHeight||html.clientHeight;uaInfo.orientation=w<h?'portrait':'landscape';html.className=html.className.replace(/ ?orientation_\w+/g,'').replace(/ [min|max|cl]+[w|h]_\d+/g,'');for(var i=allScreens-1;i>=0;i--){if(w>=screens[i]){uaInfo.maxw=screens[i];break}}widthClasses='';for(var info in uaInfo){widthClasses+=' '+info+'_'+uaInfo[info]}html.className=html.className+widthClasses;return widthClasses}window.onresize=screenSize;screenSize();function retina(){var r=window.devicePixelRatio>1;if(r){html.className+=' retina'}else{html.className+=' non-retina'}}retina();var cssbs=b.join(' ')+' js ';html.className=(cssbs+html.className.replace(/\b(no[-|_]?)?js\b/g,'')).replace(/^ /,'').replace(/ +/g,' ');return cssbs}css_browser_selector(navigator.userAgent);
</script>

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/app-server",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"license": "MIT",
"main": "./lib/index.js",
@ -11,19 +11,19 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/database": "0.7.0-alpha.10",
"@nocobase/plugin-acl": "0.7.0-alpha.10",
"@nocobase/plugin-china-region": "0.7.0-alpha.10",
"@nocobase/plugin-client": "0.7.0-alpha.10",
"@nocobase/plugin-collection-manager": "0.7.0-alpha.10",
"@nocobase/plugin-error-handler": "0.7.0-alpha.10",
"@nocobase/plugin-file-manager": "0.7.0-alpha.10",
"@nocobase/plugin-system-settings": "0.7.0-alpha.10",
"@nocobase/plugin-ui-routes-storage": "0.7.0-alpha.10",
"@nocobase/plugin-ui-schema-storage": "0.7.0-alpha.10",
"@nocobase/plugin-users": "0.7.0-alpha.10",
"@nocobase/plugin-workflow": "0.7.0-alpha.10",
"@nocobase/server": "0.7.0-alpha.10"
"@nocobase/database": "0.7.0-alpha.15",
"@nocobase/plugin-acl": "0.7.0-alpha.15",
"@nocobase/plugin-china-region": "0.7.0-alpha.15",
"@nocobase/plugin-client": "0.7.0-alpha.15",
"@nocobase/plugin-collection-manager": "0.7.0-alpha.15",
"@nocobase/plugin-error-handler": "0.7.0-alpha.15",
"@nocobase/plugin-file-manager": "0.7.0-alpha.15",
"@nocobase/plugin-system-settings": "0.7.0-alpha.15",
"@nocobase/plugin-ui-routes-storage": "0.7.0-alpha.15",
"@nocobase/plugin-ui-schema-storage": "0.7.0-alpha.15",
"@nocobase/plugin-users": "0.7.0-alpha.15",
"@nocobase/plugin-workflow": "0.7.0-alpha.15",
"@nocobase/server": "0.7.0-alpha.15"
},
"repository": {
"type": "git",

View File

@ -19,5 +19,10 @@ export default [
'@nocobase/plugin-acl',
'@nocobase/plugin-china-region',
'@nocobase/plugin-workflow',
['@nocobase/plugin-client'],
[
'@nocobase/plugin-client',
{
dist: resolve(process.cwd(), 'packages/app/client/dist'),
},
],
] as PluginsConfigurations;

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/acl",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"license": "Apache-2.0",
"licenses": [
@ -17,7 +17,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/resourcer": "0.7.0-alpha.10",
"@nocobase/resourcer": "0.7.0-alpha.15",
"json-templates": "^4.2.0"
},
"repository": {

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/actions",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"license": "Apache-2.0",
"licenses": [
@ -17,8 +17,8 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/database": "0.7.0-alpha.10",
"@nocobase/resourcer": "0.7.0-alpha.10"
"@nocobase/database": "0.7.0-alpha.15",
"@nocobase/resourcer": "0.7.0-alpha.15"
},
"repository": {
"type": "git",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/client",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"license": "Apache-2.0",
"licenses": [
{
@ -29,7 +29,7 @@
"@formily/antd": "^2.0.15",
"@formily/core": "^2.0.15",
"@formily/react": "^2.0.15",
"@nocobase/utils": "0.7.0-alpha.10",
"@nocobase/utils": "0.7.0-alpha.15",
"ahooks": "^3.0.5",
"antd": "~4.19.5",
"axios": "^0.24.0",

View File

@ -47,11 +47,11 @@ export const RoleConfigure = () => {
title: t('Configure permissions'),
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-content': '允许配置系统,包括界面配置、数据表配置、权限配置、系统配置等全部配置项',
'x-content': t('Allows configuration of the whole system, including UI, collections, permissions, etc.'),
},
'strategy.actions': {
title: t('General action permissions'),
description: '所有数据表都默认使用通用数据操作权限;同时,可以针对每个数据表单独配置权限。',
title: t('Global action permissions'),
description: t('All collections use general action permissions by default; permission configured individually will override the default one.'),
'x-component': 'StrategyActions',
'x-decorator': 'FormItem',
},
@ -59,7 +59,7 @@ export const RoleConfigure = () => {
title: t('Menu permissions'),
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-content': '新增菜单项默认允许访问',
'x-content': t('New menu items are allowed to be accessed by default.'),
},
},
}}

View File

@ -241,7 +241,7 @@ export const roleSchema: ISchema = {
properties: {
tab1: {
type: 'void',
title: '{{t("Global permissions")}}',
title: '{{t("General permissions")}}',
'x-component': 'Tabs.TabPane',
'x-component-props': {},
properties: {

View File

@ -364,8 +364,12 @@ export default {
'Role display name': '角色名称',
'Default role': '默认角色',
'All collections use general action permissions by default; permission configured individually will override the default one.': '所有数据表都默认使用通用数据操作权限;同时,可以针对每个数据表单独配置权限。',
'Allows configuration of the whole system, including UI, collections, permissions, etc.': '允许配置系统,包括界面配置、数据表配置、权限配置、系统配置等全部配置项',
'New menu items are allowed to be accessed by default.': '新增菜单项默认允许访问',
'Global permissions': '全局配置',
'General permissions': '通用配置',
'Global action permissions': '全局操作权限',
'General action permissions': '通用操作权限',
'Action display name': '操作名称',
'Allow': '允许',

View File

@ -32,7 +32,7 @@ export const calculators = [
children: [
{ value: 'add', name: '+' },
{ value: 'minus', name: '-' },
{ value: 'multipe', name: '*' },
{ value: 'multiple', name: '*' },
{ value: 'divide', name: '/' },
{ value: 'mod', name: '%' },
]
@ -396,7 +396,10 @@ export const CollectionFieldset = observer(({ value, onChange, useProps }: any)
`}>
{fields.length
? fields
.filter(field => !field.hidden)
.filter(field => (
!field.hidden
&& (field.uiSchema ? !field.uiSchema['x-read-pretty'] : true)
))
.map(field => {
const operand = typeof value[field.name] === 'string'
? parseStringValue(value[field.name], VTypes)

View File

@ -1,3 +1,4 @@
import { css } from '@emotion/css';
import React from 'react';
import { Calculation } from '../calculators';
@ -6,10 +7,10 @@ export default {
type: 'calculation',
group: 'control',
fieldset: {
calculation: {
'config.calculation': {
type: 'object',
title: '配置计算',
name: 'calculation',
name: 'config.calculation',
required: true,
'x-decorator': 'FormItem',
'x-component': 'CalculationConfig',
@ -26,6 +27,6 @@ export default {
}
},
getter() {
return <div></div>;
return <div className={css`flex-shrink: 0`}></div>;
}
};

View File

@ -1,7 +1,7 @@
import React from "react";
import { css, cx } from "@emotion/css";
import { Button, Select } from "antd";
import { CloseCircleOutlined } from '@ant-design/icons';
import { Button, Select, Tooltip } from "antd";
import { CloseCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { Trans } from "react-i18next";
import { NodeDefaultView } from ".";
@ -66,17 +66,20 @@ function CalculationGroup({ value, onChange }) {
}
return (
<div className={css`
<div className={cx('node-type-condition-group', css`
position: relative;
width: 100%;
padding: .5em 1em;
border: 1px dashed #ddd;
.node-type-condition-group{
padding: .5em 1em;
border: 1px dashed #ddd;
}
+ button{
position: absolute;
right: 0;
}
`}>
`)}>
<div className={css`
display: flex;
align-items: center;
@ -131,9 +134,9 @@ export default {
type: 'condition',
group: 'control',
fieldset: {
rejectOnFalse: {
'config.rejectOnFalse': {
type: 'boolean',
name: 'rejectOnFalse',
name: 'config.rejectOnFalse',
title: '模式',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
@ -141,13 +144,33 @@ export default {
disabled: true,
},
enum: [
{ value: true, label: '通行模式' },
{ value: false, label: '分支模式' },
{
value: true,
label: (
<Tooltip
title="判断为“是”时继续"
placement="bottom"
>
<QuestionCircleOutlined style={{ color: '#999' }} />
</Tooltip>
)
},
{
value: false,
label: (
<Tooltip
title="判断结果分为“是”和“否”两个分支,分别继续"
placement="bottom"
>
<QuestionCircleOutlined style={{ color: '#999' }} />
</Tooltip>
)
}
],
},
calculation: {
'config.calculation': {
type: 'string',
name: 'calculation',
name: 'config.calculation',
title: '条件配置',
'x-decorator': 'FormItem',
'x-component': 'CalculationConfig',

View File

@ -1,17 +1,20 @@
import React from 'react';
import { Select } from 'antd';
import React from 'react';
import { useCollectionDataSource, useCollectionManager, useCompile } from '../..';
import { useFlowContext } from '../WorkflowCanvas';
import { collection, values } from '../schemas/collection';
import { BaseTypeSet, CollectionFieldset } from '../calculators';
import { collection, values } from '../schemas/collection';
import { useFlowContext } from '../WorkflowCanvas';
export default {
title: '新增数据',
type: 'create',
group: 'model',
fieldset: {
collection,
'config.collection': {
name: 'config.collection',
...collection,
},
// multiple: {
// type: 'boolean',
// title: '多条数据',
@ -22,9 +25,9 @@ export default {
// disabled: true
// }
// },
params: {
'config.params': {
type: 'object',
name: 'params',
name: 'config.params',
title: '',
'x-decorator': 'FormItem',
properties: {

View File

@ -8,10 +8,10 @@ export default {
type: 'destroy',
group: 'model',
fieldset: {
collection,
params: {
'config.collection': collection,
'config.params': {
type: 'object',
name: 'params',
name: 'config.params',
title: '',
'x-decorator': 'FormItem',
properties: {

View File

@ -1,23 +1,24 @@
import React, { useContext } from 'react';
import { CloseOutlined, DeleteOutlined } from '@ant-design/icons';
import { css, cx } from '@emotion/css';
import { Button, Modal, Tag } from 'antd';
import { DeleteOutlined, CloseOutlined } from '@ant-design/icons';
import { ISchema, useForm } from '@formily/react';
import { Field } from '@formily/core';
import { ISchema, RecursionField, useField, useForm } from '@formily/react';
import { Registry } from '@nocobase/utils';
import { Button, Modal, Tag } from 'antd';
import React, { useContext } from 'react';
import { SchemaComponent, useActionContext, useAPIClient, useCollection, useRequest, useResourceActionContext } from '../..';
import { nodeBlockClass, nodeCardClass, nodeClass, nodeHeaderClass, nodeTitleClass } from '../style';
import { AddButton, useFlowContext } from '../WorkflowCanvas';
import { nodeClass, nodeCardClass, nodeHeaderClass, nodeTitleClass, nodeBlockClass } from '../style';
import query from './query';
import create from './create';
import update from './update';
import destroy from './destroy';
import condition from './condition';
import parallel from './parallel';
import calculation from './calculation';
import condition from './condition';
import create from './create';
import destroy from './destroy';
import parallel from './parallel';
import query from './query';
import update from './update';
@ -45,7 +46,7 @@ instructions.register('condition', condition);
instructions.register('parallel', parallel);
instructions.register('calculation', calculation);
function useUpdateConfigAction() {
function useUpdateAction() {
const form = useForm();
const api = useAPIClient();
const ctx = useActionContext();
@ -53,14 +54,13 @@ function useUpdateConfigAction() {
const data = useNodeContext();
return {
async run() {
await form.submit();
await api.resource('flow_nodes', data.id).update({
filterByTk: data.id,
values: {
config: {
...data.config,
...form.values
}
},
title: form.values.title,
config: form.values.config
}
});
ctx.setVisible(false);
refresh();
@ -148,6 +148,14 @@ export function RemoveButton() {
);
}
function Fieldset({ schema }) {
const field = useField<Field>();
return (
<RecursionField basePath={field.address} schema={schema} />
);
}
export function NodeDefaultView(props) {
const { data, children } = props;
const instruction = instructions.get(data.type);
@ -166,63 +174,75 @@ export function NodeDefaultView(props) {
</div>
<SchemaComponent
scope={instruction.scope}
components={instruction.components}
components={{
...instruction.components,
Fieldset
}}
schema={{
type: 'void',
properties: {
view: instruction.view,
...(Object.keys(instruction.fieldset).length
? {
config: {
config: {
type: 'void',
title: '配置节点',
'x-component': 'Action.Link',
'x-component-props': {
type: 'primary',
},
properties: {
drawer: {
type: 'void',
title: '配置节点',
'x-component': 'Action.Link',
'x-component-props': {
type: 'primary',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues(options) {
const data = useNodeContext();
return useRequest(() => {
return Promise.resolve({ data });
}, options);
}
},
properties: {
drawer: {
title: {
type: 'string',
name: 'title',
title: '节点名称',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
config: {
type: 'void',
title: '配置节点',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues(options) {
const node = useNodeContext();
return useRequest(() => {
return Promise.resolve({ data: node.config });
}, options);
}
},
name: 'config',
'x-component': 'fieldset',
'x-component-props': {},
properties: instruction.fieldset
},
actions: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
...instruction.fieldset,
actions: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
cancel: {
title: '{{t("Cancel")}}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ cm.useCancelAction }}',
},
},
submit: {
title: '{{t("Submit")}}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: useUpdateConfigAction,
},
},
cancel: {
title: '{{t("Cancel")}}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ cm.useCancelAction }}',
},
} as ISchema
}
}
},
submit: {
title: '{{t("Submit")}}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: useUpdateAction,
},
},
},
} as ISchema
}
}
}
: {})
}
}
}}
/>

View File

@ -1,6 +1,6 @@
import React, { useState } from "react";
import { css, cx } from "@emotion/css";
import { PlusOutlined } from '@ant-design/icons';
import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { NodeDefaultView } from ".";
import { Branch, useFlowContext } from "../WorkflowCanvas";
@ -13,17 +13,37 @@ export default {
type: 'parallel',
group: 'control',
fieldset: {
mode: {
'config.mode': {
type: 'string',
name: 'mode',
name: 'config.mode',
title: '模式',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
},
enum: [
{ value: 'all', label: '全部成功' },
{ value: 'any', label: '任意成功' },
{
value: 'all',
label: (
<Tooltip
title="全部分支都成功后才能继续"
placement="bottom"
>
<QuestionCircleOutlined style={{ color: '#999' }} />
</Tooltip>
)
},
{
value: 'any',
label: (
<Tooltip
title="任意分支成功后就继续"
placement="bottom"
>
<QuestionCircleOutlined style={{ color: '#999' }} />
</Tooltip>
)
},
// { value: 'race', label: '任意退出' },
],
default: 'all'

View File

@ -12,20 +12,20 @@ export default {
type: 'query',
group: 'model',
fieldset: {
collection,
multiple: {
'config.collection': collection,
'config.multiple': {
type: 'boolean',
title: '多条数据',
name: 'multiple',
name: 'config.multiple',
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-component-props': {
disabled: true
}
},
params: {
'config.params': {
type: 'object',
name: 'params',
name: 'config.params',
title: '',
'x-decorator': 'FormItem',
properties: {

View File

@ -7,10 +7,10 @@ export default {
type: 'update',
group: 'model',
fieldset: {
collection,
params: {
'config.collection': collection,
'config.params': {
type: 'object',
name: 'params',
name: 'config.params',
title: '',
'x-decorator': 'FormItem',
properties: {

View File

@ -6,7 +6,7 @@ import { useCollectionFilterOptions } from "../../collection-manager/action-hook
export const collection = {
type: 'string',
title: '数据表',
name: 'collection',
name: 'config.collection',
required: true,
'x-reactions': ['{{useCollectionDataSource()}}'],
'x-decorator': 'FormItem',
@ -16,7 +16,7 @@ export const collection = {
export const values = {
type: 'object',
title: '数据内容',
name: 'values',
name: 'config.params.values',
'x-decorator': 'FormItem',
'x-decorator-props': {
labelAlign: 'left',
@ -29,7 +29,7 @@ export const values = {
useProps() {
const { getCollectionFields } = useCollectionManager();
const { values: form } = useForm();
const fields = getCollectionFields(form.collection);
const fields = getCollectionFields(form?.config?.collection);
return { fields };
}
}
@ -38,7 +38,7 @@ export const values = {
export const filter = {
type: 'object',
title: '筛选条件',
name: 'filter',
name: 'config.params.filter',
'x-decorator': 'FormItem',
'x-decorator-props': {
labelAlign: 'left',
@ -50,14 +50,12 @@ export const filter = {
'x-component-props': {
useProps() {
const { values } = useForm();
const options = useCollectionFilterOptions(values.collection);
const options = useCollectionFilterOptions(values.config.collection);
return {
options,
className: css`
position: relative;
width: 100%;
padding: .5em 1em;
border: 1px dashed #ddd;
`
};
},

View File

@ -15,16 +15,6 @@ const collection = {
required: true,
} as ISchema,
},
// {
// type: 'string',
// name: 'description',
// interface: 'textarea',
// uiSchema: {
// title: '描述',
// type: 'string',
// 'x-component': 'TextArea',
// } as ISchema,
// },
{
type: 'string',
name: 'type',
@ -37,6 +27,17 @@ const collection = {
enum: [
{ value: 'model', label: '数据变动' }
],
required: true,
} as ISchema,
},
{
type: 'string',
name: 'description',
interface: 'textarea',
uiSchema: {
title: '描述',
type: 'string',
'x-component': 'Input.TextArea',
} as ISchema,
},
{
@ -95,6 +96,13 @@ export const workflowSchema: ISchema = {
type: 'void',
title: '删除',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ cm.useBulkDestroyAction }}',
confirm: {
title: "{{t('Delete record')}}",
content: "{{t('Are you sure you want to delete it?')}}",
},
},
},
create: {
type: 'void',
@ -114,11 +122,11 @@ export const workflowSchema: ISchema = {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
description: {
type: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
type: {
description: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},

View File

@ -16,6 +16,7 @@ function useUpdateConfigAction() {
const { refresh } = useResourceActionContext();
return {
async run() {
await form.submit();
await api.resource('workflows', record.id).update({
filterByTk: record.id,
values: {

View File

@ -21,10 +21,10 @@ export default {
'x-component': 'Select',
'x-component-props': {
options: [
{ value: 1, label: '新增数据' },
{ value: 2, label: '更新数据' },
{ value: 3, label: '新增或更新数据' },
{ value: 4, label: '删除数据' }
{ value: 1, label: '新增数据' },
{ value: 2, label: '更新数据' },
{ value: 3, label: '新增或更新数据' },
{ value: 4, label: '删除数据' }
]
}
},

View File

@ -1,6 +1,6 @@
{
"name": "create-nocobase-app",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "src/index.js",
"license": "Apache-2.0",
"licenses": [
@ -16,6 +16,7 @@
"commander": "^8.2.0",
"execa": "5",
"fs-extra": "^10.0.1",
"lodash": "^4.17.21",
"ora": "^5.4.1",
"tar": "^6.1.11"
},

View File

@ -0,0 +1,3 @@
/src/.umi
/src/.umi-production
/src/.umi-test

View File

@ -1,7 +1,7 @@
const execa = require('execa');
const axios = require('axios');
const fs = require('fs');
const fsP = require('fs/promises');
const fsP = require('fs').promises;
const tar = require('tar');
const { join } = require('path');
const crypto = require('crypto');
@ -40,9 +40,9 @@ module.exports = async (packageName, target) => {
cwd: target,
strip: 1,
k: true,
filter(path, entry) {
return !(path.startsWith('package/lib') || path.startsWith('package/esm') || path.startsWith('package/dist'));
},
// filter(path, entry) {
// return !(path.startsWith('package/lib') || path.startsWith('package/esm') || path.startsWith('package/dist'));
// },
});
await fsP.unlink(tarballFile);

View File

@ -15,6 +15,7 @@ module.exports = (opts) => {
'nocobase-prod': 'cross-env DOTENV_CONFIG_PATH=.env node -r dotenv/config packages/app/server/lib/index.js',
'start-client': 'cd packages/app/client && npm run start',
'start-server': 'npm run nocobase start',
'start-pm2': 'pm2-runtime start --node-args="-r dotenv/config" packages/app/server/lib/index.js -- start',
build: 'lerna run build',
'build-docs': 'dumi build',
test: 'node ./jest.cli.js -i',
@ -24,6 +25,11 @@ module.exports = (opts) => {
'@types/react': '^17.0.0',
'@types/react-dom': '^17.0.0',
},
dependencies: {
'cross-env': '^7.0.3',
dotenv: '^10.0.0',
pm2: '^5.2.0',
},
devDependencies: {
'@testing-library/react': '^12.1.2',
'@types/jest': '^26.0.0',
@ -33,8 +39,6 @@ module.exports = (opts) => {
'@typescript-eslint/eslint-plugin': '^4.9.1',
'@typescript-eslint/parser': '^4.8.2',
concurrently: '^7.0.0',
'cross-env': '^7.0.3',
dotenv: '^10.0.0',
eslint: '^7.14.0',
'eslint-config-prettier': '^7.0.0',
'eslint-plugin-import': '^2.13.0',

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/database",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
@ -17,7 +17,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/utils": "0.7.0-alpha.10",
"@nocobase/utils": "0.7.0-alpha.15",
"async-mutex": "^0.3.2",
"deepmerge": "^4.2.2",
"flat": "^5.0.2",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/resourcer",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/server",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"types": "./lib/index.d.ts",
"license": "Apache-2.0",
@ -18,10 +18,10 @@
"dependencies": {
"@koa/cors": "^3.1.0",
"@koa/router": "^9.4.0",
"@nocobase/acl": "0.7.0-alpha.10",
"@nocobase/actions": "0.7.0-alpha.10",
"@nocobase/database": "0.7.0-alpha.10",
"@nocobase/resourcer": "0.7.0-alpha.10",
"@nocobase/acl": "0.7.0-alpha.15",
"@nocobase/actions": "0.7.0-alpha.15",
"@nocobase/database": "0.7.0-alpha.15",
"@nocobase/resourcer": "0.7.0-alpha.15",
"commander": "^8.1.0",
"dotenv": "^8.2.0",
"find-package-json": "^1.2.0",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/test",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"types": "./lib/index.d.ts",
"license": "Apache-2.0",
@ -16,7 +16,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/server": "0.7.0-alpha.10",
"@nocobase/server": "0.7.0-alpha.15",
"@types/supertest": "^2.0.11",
"mockjs": "^1.1.0",
"mysql2": "^2.1.0",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/utils",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"types": "./lib/index.d.ts",
"license": "Apache-2.0",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-acl",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"license": "Apache-2.0",
"licenses": [
@ -17,9 +17,9 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/acl": "0.7.0-alpha.10",
"@nocobase/database": "0.7.0-alpha.10",
"@nocobase/server": "0.7.0-alpha.10"
"@nocobase/acl": "0.7.0-alpha.15",
"@nocobase/database": "0.7.0-alpha.15",
"@nocobase/server": "0.7.0-alpha.15"
},
"repository": {
"type": "git",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-action-logs",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -15,7 +15,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-china-region",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -18,7 +18,7 @@
"china-division": "^2.4.0"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-client",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -15,10 +15,10 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/server": "0.7.0-alpha.10"
"@nocobase/server": "0.7.0-alpha.15"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-collection-manager",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -15,7 +15,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-error-handler",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"description": "",
"license": "Apache-2.0",
"licenses": [
@ -18,7 +18,7 @@
},
"dependencies": {
"@formily/json-schema": "^2.0.15",
"@nocobase/server": "0.7.0-alpha.10"
"@nocobase/server": "0.7.0-alpha.15"
},
"repository": {
"type": "git",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-file-manager",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -16,16 +16,17 @@
},
"dependencies": {
"@koa/multer": "^3.0.0",
"@nocobase/server": "0.7.0-alpha.10",
"@nocobase/server": "0.7.0-alpha.15",
"aws-sdk": "^2.2.32",
"koa-static": "^5.0.0",
"mkdirp": "~0.5.4",
"mime-match": "^1.0.2",
"multer": "^1.4.2",
"multer-aliyun-oss": "1.1.1",
"multer-s3": "^2.10.0"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10",
"@nocobase/test": "0.7.0-alpha.15",
"@types/koa-multer": "^1.0.1",
"@types/multer": "^1.4.5"
},

View File

@ -46,7 +46,6 @@ describe('action', () => {
size: 13,
mimetype: 'text/plain',
meta: {},
storageId: 1,
};
// 文件上传和解析是否正常
@ -119,7 +118,6 @@ describe('action', () => {
// see: https://github.com/ljharb/qs/issues/91
// 或考虑使用 query-string 库的 parseNumbers 等配置项
meta: { width: '100', height: '100' },
storageId: 1,
};
// 上传正常返回
expect(body.data).toMatchObject(matcher);

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-multi-app-manager",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -15,7 +15,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/server": "0.7.0-alpha.10"
"@nocobase/server": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-notifications",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -18,7 +18,7 @@
"nodemailer": "^6.6.1"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10",
"@nocobase/test": "0.7.0-alpha.15",
"@types/nodemailer": "6.4.4",
"nodemailer-mock": "^1.5.11"
},

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-system-settings",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -15,7 +15,7 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-ui-routes-storage",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -18,7 +18,7 @@
"flat-to-nested": "^1.1.1"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-ui-schema-storage",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -16,7 +16,7 @@
},
"devDependencies": {
"@formily/json-schema": "^2.0.15",
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-users",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -18,7 +18,7 @@
"jsonwebtoken": "^8.5.1"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10",
"@nocobase/test": "0.7.0-alpha.15",
"@types/jsonwebtoken": "^8.5.8"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/plugin-workflow",
"version": "0.7.0-alpha.10",
"version": "0.7.0-alpha.15",
"main": "lib/index.js",
"license": "Apache-2.0",
"licenses": [
@ -15,14 +15,14 @@
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"@nocobase/actions": "0.7.0-alpha.10",
"@nocobase/database": "0.7.0-alpha.10",
"@nocobase/server": "0.7.0-alpha.10",
"@nocobase/utils": "0.7.0-alpha.10",
"@nocobase/actions": "0.7.0-alpha.15",
"@nocobase/database": "0.7.0-alpha.15",
"@nocobase/server": "0.7.0-alpha.15",
"@nocobase/utils": "0.7.0-alpha.15",
"json-templates": "^4.2.0"
},
"devDependencies": {
"@nocobase/test": "0.7.0-alpha.10"
"@nocobase/test": "0.7.0-alpha.15"
},
"gitHead": "a00b45a2686695c5f4824d074ac5e1aff210793a"
}

View File

@ -148,7 +148,7 @@ function minus(a, b) {
return a - b;
}
function multipe(...args) {
function multiple(...args) {
return args.reduce((result, a) => result * a, 1);
}
@ -162,13 +162,13 @@ function mod(a, b) {
calculators.register('add', add);
calculators.register('minus', minus);
calculators.register('multipe', multipe);
calculators.register('multiple', multiple);
calculators.register('divide', divide);
calculators.register('mod', mod);
calculators.register('+', add);
calculators.register('-', minus);
calculators.register('*', multipe);
calculators.register('*', multiple);
calculators.register('/', divide);
calculators.register('%', mod);

View File

@ -11106,6 +11106,11 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimist@^1.2.6:
version "1.2.6"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
minipass-collect@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617"
@ -11217,6 +11222,13 @@ mkdirp@1.0.4, mkdirp@1.x, mkdirp@^1.0.3, mkdirp@^1.0.4:
dependencies:
minimist "^1.2.5"
mkdirp@~0.5.4:
version "0.5.6"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
dependencies:
minimist "^1.2.6"
mockjs@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/mockjs/-/mockjs-1.1.0.tgz#e6a0c378e91906dbaff20911cc0273b3c7d75b06"