Feat/collection templates (#1124)

* feat: add collection templates

* feat:  collection templates

* feat:  collection templates

* feat:  collection templates

* feat:  collection templates

* feat: collection templates

* feat: calendar collection template

* feat: no id does not support sorting

* feat: collection template edit

* feat: collectiom templates code improve

* feat: collection template supports configurable field interface

* feat: collection template supports configurable field interface

* feat: establish relation field when there is no id

* feat: collection templates

* feat: collection templates locale

* feat: calendar collection

* feat: calendar collection default fields

* feat: code optimization

* feat: code optimization

* feat: code optimization

* feat: collectin template fix

* feat: add sample-custom-collection-template

* feat: code optimization

* feat: code optimization

* feat: code optimization

* feat: code optimization

* feat: import code

* feat: collection template local

* feat: code opimization

* feat: code opimization

* feat: code opimization

* feat: code opimization

* feat: code opimization

* feat: collection template local

* feat: collection template local

* fix(collection-manager): exclude reverse parameters when overriding

* feat: update docs

* feat: disabled

* feat: improve code

* feat: update submodule

* feat: submodules: true

* fix: token

* fix: with ssh-key

* fix: update dockerfile

* fix: ci

* fix: ci

* fix: ci

* fix: ci

* fix: --no-verify-access

* fix: ci

* fix: ci

* fix: ci

* fix: missing env

* fix: env

Co-authored-by: chenos <chenlinxh@gmail.com>
Co-authored-by: chareice <chareice@live.com>
This commit is contained in:
katherinehhh 2022-11-29 11:31:30 +08:00 committed by GitHub
parent f7f58bfe99
commit 4085ed0db7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1149 additions and 663 deletions

View File

@ -24,6 +24,9 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
ssh-key: ${{ secrets.SUBMODULE_SSH_KEY }}
submodules: true
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx - name: Set up Docker Buildx
@ -51,7 +54,7 @@ jobs:
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: . context: .
file: Dockerfile file: Dockerfile.acr
build-args: | build-args: |
VERDACCIO_URL=http://localhost:4873/ VERDACCIO_URL=http://localhost:4873/
COMMIT_HASH=${GITHUB_SHA} COMMIT_HASH=${GITHUB_SHA}

64
Dockerfile.acr Normal file
View File

@ -0,0 +1,64 @@
FROM node:16 as builder
ARG VERDACCIO_URL=http://host.docker.internal:10104/
ARG COMIT_HASH
RUN apt-get update && apt-get install -y jq
WORKDIR /tmp
COPY . /tmp
RUN npx npm-cli-adduser --username test --password test -e test@nocobase.com -r $VERDACCIO_URL
RUN cd /tmp && \
NEWVERSION="$(cat lerna.json | jq '.version' | tr -d '"').$(date +%s)" \
&& tmp=$(mktemp) \
&& jq ".version = \"${NEWVERSION}\"" lerna.json > "$tmp" && mv "$tmp" lerna.json
RUN yarn install && yarn nocobase install && yarn pm add graph-collection-manager && yarn build
RUN git checkout -b release \
&& yarn version:alpha -y
RUN cd packages/pro-plugins && git checkout -b release \
&& git config user.email "test@mail.com" \
&& git config user.name "test" && git add . \
&& git commit -m "chore(versions): test publish packages xxx"
RUN git config user.email "test@mail.com" \
&& git config user.name "test" && git add . \
&& git commit -m "chore(versions): test publish packages xxx" \
&& git submodule update --init --recursive -- packages/pro-plugins
RUN yarn release:force --no-verify-access --no-git-reset --registry $VERDACCIO_URL
RUN yarn config set registry $VERDACCIO_URL
WORKDIR /app
RUN cd /app \
&& yarn config set network-timeout 600000 -g \
&& yarn create nocobase-app my-nocobase-app -a \
-e APP_ENV=production \
-e PLUGIN_PACKAGE_PREFIX=@nocobase/plugin-,@nocobase/preset-,@nocobase/plugin-pro- \
-e PRESET_NOCOBASE_PLUGINS=error-handler,collection-manager,ui-schema-storage,ui-routes-storage,file-manager,system-settings,verification,users,acl,china-region,workflow,client,export,import,audit-logs,graph-collection-manager \
&& cd /app/my-nocobase-app \
&& yarn install --production \
&& yarn add @nocobase/plugin-pro-graph-collection-manager -W
RUN cd /app \
&& rm -rf my-nocobase-app/packages/app/client/src/.umi \
&& rm -rf nocobase.tar.gz \
&& find ./my-nocobase-app/node_modules/china-division/dist -name '*.csv' -delete \
&& find ./my-nocobase-app/node_modules/china-division/dist -name '*.sqlite' -delete \
&& tar -zcf ./nocobase.tar.gz -C /app/my-nocobase-app .
FROM node:16-stretch-slim
RUN apt-get update && apt-get install -y nginx
RUN rm -rf /etc/nginx/sites-enabled/default
COPY ./docker/nocobase/nocobase.conf /etc/nginx/sites-enabled/nocobase.conf
COPY --from=builder /app/nocobase.tar.gz /app/nocobase.tar.gz
WORKDIR /app/nocobase
RUN mkdir -p /app/nocobase/storage/uploads/ && echo "$COMIT_HASH" >> /app/nocobase/storage/uploads/COMIT_HASH
COPY ./docker/nocobase/docker-entrypoint.sh /app/
CMD ["/app/docker-entrypoint.sh"]

View File

@ -1,47 +0,0 @@
FROM node:16 as builder
ARG VERDACCIO_URL=https://pkgs.nocobase.com/
RUN apt-get update && apt-get install -y jq
WORKDIR /tmp
COPY . /tmp
RUN npx npm-cli-adduser --username test --password test -e test@nocobase.com -r $VERDACCIO_URL
RUN cd /tmp && \
NEWVERSION="$(cat lerna.json | jq '.version' | tr -d '"').$(date +%s)" \
&& tmp=$(mktemp) \
&& jq ".version = \"${NEWVERSION}\"" lerna.json > "$tmp" && mv "$tmp" lerna.json
RUN yarn install && yarn build
RUN git checkout -b release \
&& yarn version:alpha -y \
&& git config user.email "test@mail.com" \
&& git config user.name "test" && git add . \
&& git commit -m "chore(versions): test publish packages xxx" \
&& yarn release:force --registry $VERDACCIO_URL
RUN yarn config set registry $VERDACCIO_URL
WORKDIR /app
RUN cd /app \
&& yarn create nocobase-app my-nocobase-app -a -e APP_ENV=production \
&& cd /app/my-nocobase-app \
&& yarn install --production
RUN cd /app \
&& rm -rf my-nocobase-app/packages/app/client/src/.umi \
&& rm -rf nocobase.tar.gz \
&& find ./my-nocobase-app/node_modules/china-division/dist -name '*.csv' -delete \
&& find ./my-nocobase-app/node_modules/china-division/dist -name '*.sqlite' -delete \
&& tar -zcf ./nocobase.tar.gz -C /app/my-nocobase-app .
FROM node:16-stretch-slim
RUN apt-get update && apt-get install -y nginx
RUN rm -rf /etc/nginx/sites-enabled/default
COPY ./docker/nocobase/nocobase.conf /etc/nginx/sites-enabled/nocobase.conf
COPY --from=builder /app/nocobase.tar.gz /app/nocobase.tar.gz
WORKDIR /app/nocobase
COPY ./docker/nocobase/docker-entrypoint.sh /app/
CMD ["/app/docker-entrypoint.sh"]

View File

@ -0,0 +1,79 @@
# v0.8.1: Collection 模板
<img src="./v08-1-collection-templates/v08-1-collection-templates.jpg">
## 为什么需要 Collection 模板?
待补充
## 配置参数说明
```ts
interface ICollectionTemplate {
name: string;
title?: string;
/** 排序 */
order?: number;
/** 默认配置 */
default?: CollectionOptions;
/** UI 可配置的 CollectionOptions 参数(添加或编辑的 Collection 表单的字段) */
configurableProperties?: Record<string, ISchema>;
/** 当前模板可用的字段类型 */
availableFieldInterfaces?: AvailableFieldInterfacesInclude | AvailableFieldInterfacesExclude;
}
interface AvailableFieldInterfacesInclude {
include?: any[];
}
interface AvailableFieldInterfacesExclude {
exclude?: any[];
}
interface CollectionOptions {
/**
* 自动生成 id
* @default true
* */
autoGenId?: boolean;
/** 创建人 */
createdBy?: boolean;
/** 最后更新人 */
updatedBy?: boolean;
/** 创建日期 */
createdAt?: boolean;
/** 更新日期 */
updatedAt?: boolean;
/** 可排序 */
sortable?: boolean;
/* 树结构 */
tree?: string;
/* 日志 */
logging?: boolean;
/** 继承 */
inherits: string | string[];
/* 字段列表 */
fields?: FieldOptions[];
}
```
## 示例
创建时都不需要 autoGenId并且只提供 title 和 name 配置项
```ts
import { collectionConfigurableProperties } from '@nocobase/client';
{
default: {
autoGenId: false,
fields: [],
},
configurableProperties: {
...collectionConfigurableProperties('name', 'title'),
},
}
```
完整插件示例参考:[samples/custom-collection-template](https://github.com/nocobase/nocobase/tree/feat/collection-templates/packages/samples/custom-collection-template)

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

View File

@ -1,20 +1,24 @@
import { Spin } from 'antd'; import { Spin } from 'antd';
import React, { useContext, useState } from 'react'; import React, { useContext, useState } from 'react';
import { keyBy } from 'lodash';
import { useAPIClient, useRequest } from '../api-client'; import { useAPIClient, useRequest } from '../api-client';
import { CollectionManagerSchemaComponentProvider } from './CollectionManagerSchemaComponentProvider'; import { CollectionManagerSchemaComponentProvider } from './CollectionManagerSchemaComponentProvider';
import { CollectionManagerContext } from './context'; import { CollectionManagerContext } from './context';
import * as defaultInterfaces from './interfaces'; import * as defaultInterfaces from './interfaces';
import { CollectionManagerOptions } from './types'; import { CollectionManagerOptions } from './types';
import { templateOptions } from '../collection-manager/Configuration/templates';
export const CollectionManagerProvider: React.FC<CollectionManagerOptions> = (props) => { export const CollectionManagerProvider: React.FC<CollectionManagerOptions> = (props) => {
const { service, interfaces, collections = [], refreshCM } = props; const { service, interfaces, collections = [], refreshCM, templates } = props;
const defaultTemplates = keyBy(templateOptions(), (item) => item.name);
const ctx = useContext(CollectionManagerContext); const ctx = useContext(CollectionManagerContext);
return ( return (
<CollectionManagerContext.Provider <CollectionManagerContext.Provider
value={{ value={{
...ctx, ...ctx,
service, service,
interfaces: { ...defaultInterfaces, ...interfaces, ...ctx.interfaces }, interfaces: { ...defaultInterfaces, ...interfaces },
templates: { ...defaultTemplates, ...templates },
collections, collections,
refreshCM, refreshCM,
}} }}

View File

@ -17,6 +17,10 @@ import {
OverridingCollectionField, OverridingCollectionField,
ViewCollectionField, ViewCollectionField,
ViewFieldAction, ViewFieldAction,
AddCollection,
AddCollectionAction,
EditCollection,
EditCollectionAction,
} from './Configuration'; } from './Configuration';
const schema: ISchema = { const schema: ISchema = {
@ -53,6 +57,10 @@ export const CollectionManagerPane = () => {
ConfigurationTable, ConfigurationTable,
AddFieldAction, AddFieldAction,
AddCollectionField, AddCollectionField,
AddCollection,
AddCollectionAction,
EditCollection,
EditCollectionAction,
EditFieldAction, EditFieldAction,
EditCollectionField, EditCollectionField,
OverridingCollectionField, OverridingCollectionField,
@ -99,6 +107,8 @@ export const CollectionManagerShortcut2 = () => {
EditFieldAction, EditFieldAction,
OverridingFieldAction, OverridingFieldAction,
ViewFieldAction, ViewFieldAction,
AddCollectionAction,
EditCollectionAction,
}} }}
/> />
</ActionContext.Provider> </ActionContext.Provider>

View File

@ -0,0 +1,282 @@
import { DownOutlined, PlusOutlined } from '@ant-design/icons';
import { ArrayTable } from '@formily/antd';
import { ISchema, useForm } from '@formily/react';
import { uid } from '@formily/shared';
import { Button, Dropdown, Menu } from 'antd';
import { cloneDeep } from 'lodash';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useRequest } from '../../api-client';
import { RecordProvider, useRecord } from '../../record-provider';
import { ActionContext, SchemaComponent, useActionContext, useCompile } from '../../schema-component';
import { useCancelAction } from '../action-hooks';
import { useCollectionManager } from '../hooks';
import { useResourceActionContext, useResourceContext } from '../ResourceActionProvider';
import * as components from './components';
import { templateOptions } from './templates';
const getSchema = (schema, record: any, compile): ISchema => {
if (!schema) {
return;
}
const properties = cloneDeep(schema.configurableProperties) as any;
if (schema.hasDefaultValue === true) {
properties['defaultValue'] = cloneDeep(schema.default.uiSchema);
properties['defaultValue']['title'] = compile('{{ t("Default value") }}');
properties['defaultValue']['x-decorator'] = 'FormItem';
}
const initialValue: any = {
name: `f_${uid()}`,
template: schema.name,
...cloneDeep(schema.default),
};
if (initialValue.reverseField) {
initialValue.reverseField.name = `f_${uid()}`;
}
return {
type: 'object',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Action.Drawer',
'x-component-props': {
getContainer: '{{ getContainer }}',
},
'x-decorator': 'Form',
'x-decorator-props': {
useValues(options) {
return useRequest(
() =>
Promise.resolve({
data: initialValue,
}),
options,
);
},
},
title: '{{ t("Create collection") }}',
properties: {
summary: {
type: 'void',
'x-component': 'FieldSummary',
'x-component-props': {
schemaKey: schema.name,
},
},
// @ts-ignore
...properties,
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: '{{ t("Cancel") }}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ useCancelAction }}',
},
},
action2: {
title: '{{ t("Submit") }}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: () => useCreateCollection(),
},
},
},
},
},
},
},
};
};
const useDefaultCollectionFields = (values) => {
let defaults = values.fields ? [...values.fields] : [];
const { autoGenId = true, createdAt = true, createdBy = true, updatedAt = true, updatedBy = true } = values;
if (autoGenId) {
const pk = values.fields.find((f) => f.primaryKey);
if (!pk) {
defaults.push({
name: 'id',
type: 'bigInt',
autoIncrement: true,
primaryKey: true,
allowNull: false,
uiSchema: { type: 'number', title: '{{t("ID")}}', 'x-component': 'InputNumber', 'x-read-pretty': true },
interface: 'id',
});
}
}
if (createdAt) {
defaults.push({
name: 'createdAt',
interface: 'createdAt',
type: 'date',
field: 'createdAt',
uiSchema: {
type: 'datetime',
title: '{{t("Created at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
});
}
if (createdBy) {
defaults.push({
name: 'createdBy',
interface: 'createdBy',
type: 'belongsTo',
target: 'users',
foreignKey: 'createdById',
uiSchema: {
type: 'object',
title: '{{t("Created by")}}',
'x-component': 'RecordPicker',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
});
}
if (updatedAt) {
defaults.push({
type: 'date',
field: 'updatedAt',
name: 'updatedAt',
interface: 'updatedAt',
uiSchema: {
type: 'string',
title: '{{t("Last updated at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
});
}
if (updatedBy) {
defaults.push({
type: 'belongsTo',
target: 'users',
foreignKey: 'updatedById',
name: 'updatedBy',
interface: 'updatedBy',
uiSchema: {
type: 'object',
title: '{{t("Last updated by")}}',
'x-component': 'RecordPicker',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
});
}
// 其他
return defaults;
};
const useCreateCollection = () => {
const form = useForm();
const { refreshCM } = useCollectionManager();
const ctx = useActionContext();
const { refresh } = useResourceActionContext();
const { resource } = useResourceContext();
return {
async run() {
await form.submit();
const values = cloneDeep(form.values);
const fields = useDefaultCollectionFields(values);
console.log(fields);
if (values.autoCreateReverseField) {
} else {
delete values.reverseField;
}
delete values.id;
delete values.autoCreateReverseField;
await resource.create({
values: {
logging: true,
...values,
fields,
},
});
ctx.setVisible(false);
await form.reset();
refresh();
await refreshCM();
},
};
};
export const AddCollection = (props) => {
const record = useRecord();
return <AddCollectionAction item={record} {...props} />;
};
export const AddCollectionAction = (props) => {
const { scope, getContainer, item: record, children, trigger, align } = props;
const { getTemplate } = useCollectionManager();
const [visible, setVisible] = useState(false);
const [schema, setSchema] = useState({});
const compile = useCompile();
const { t } = useTranslation();
return (
<RecordProvider record={record}>
<ActionContext.Provider value={{ visible, setVisible }}>
<Dropdown
getPopupContainer={getContainer}
trigger={trigger}
align={align}
overlay={
<Menu
style={{
maxHeight: '60vh',
overflow: 'auto',
}}
onClick={(info) => {
const schema = getSchema(getTemplate(info.key), record, compile);
setSchema(schema);
setVisible(true);
}}
>
{templateOptions().map((option) => {
return <Menu.Item key={option.name}>{compile(option.title)}</Menu.Item>;
})}
</Menu>
}
>
{children || (
<Button icon={<PlusOutlined />} type={'primary'}>
{t('Create collection')} <DownOutlined />
</Button>
)}
</Dropdown>
<SchemaComponent
schema={schema}
components={{ ...components, ArrayTable }}
scope={{
getContainer,
useCancelAction,
createOnly: true,
useCreateCollection,
record,
showReverseFieldConfig: true,
...scope,
}}
/>
</ActionContext.Provider>
</RecordProvider>
);
};

View File

@ -9,12 +9,12 @@ import { useTranslation } from 'react-i18next';
import { useRequest } from '../../api-client'; import { useRequest } from '../../api-client';
import { RecordProvider, useRecord } from '../../record-provider'; import { RecordProvider, useRecord } from '../../record-provider';
import { ActionContext, SchemaComponent, useActionContext, useCompile } from '../../schema-component'; import { ActionContext, SchemaComponent, useActionContext, useCompile } from '../../schema-component';
import { useCancelAction, useCreateAction } from '../action-hooks'; import { useCancelAction } from '../action-hooks';
import { useCollectionManager } from '../hooks'; import { useCollectionManager } from '../hooks';
import { IField } from '../interfaces/types'; import { IField } from '../interfaces/types';
import { useResourceActionContext, useResourceContext } from '../ResourceActionProvider'; import { useResourceActionContext, useResourceContext } from '../ResourceActionProvider';
import * as components from './components'; import * as components from './components';
import { getOptions } from './interfaces'; import { options } from './interfaces';
const getSchema = (schema: IField, record: any, compile) => { const getSchema = (schema: IField, record: any, compile) => {
if (!schema) { if (!schema) {
@ -114,7 +114,6 @@ export const useCollectionFieldFormValues = () => {
const useCreateCollectionField = () => { const useCreateCollectionField = () => {
const form = useForm(); const form = useForm();
const { run } = useCreateAction();
const { refreshCM } = useCollectionManager(); const { refreshCM } = useCollectionManager();
const ctx = useActionContext(); const ctx = useActionContext();
const { refresh } = useResourceActionContext(); const { refresh } = useResourceActionContext();
@ -144,11 +143,44 @@ export const AddCollectionField = (props) => {
export const AddFieldAction = (props) => { export const AddFieldAction = (props) => {
const { scope, getContainer, item: record, children, trigger, align } = props; const { scope, getContainer, item: record, children, trigger, align } = props;
const { getInterface } = useCollectionManager(); const { getInterface, getTemplate } = useCollectionManager();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [schema, setSchema] = useState({}); const [schema, setSchema] = useState({});
const compile = useCompile(); const compile = useCompile();
const { t } = useTranslation(); const { t } = useTranslation();
const getFieldOptions = () => {
const { availableFieldInterfaces } = getTemplate(record.template) || {};
const { exclude, include } = availableFieldInterfaces || {};
const optionArr = [];
options.forEach((v) => {
if (v.key === 'systemInfo') {
optionArr.push({
...v,
children: v.children.filter((v) => {
if (v.value === 'id') {
return typeof record['autoGenId'] === 'boolean' ? record['autoGenId'] : true;
} else {
return typeof record[v.value] === 'boolean' ? record[v.value] : true;
}
}),
});
} else {
const children = v.children.filter((v) => {
if (include?.length) {
return include.includes(v.value);
} else if (exclude?.length) {
return !exclude.includes(v.value);
}
return true;
});
optionArr.push({
...v,
children,
});
}
});
return optionArr;
};
return ( return (
<RecordProvider record={record}> <RecordProvider record={record}>
<ActionContext.Provider value={{ visible, setVisible }}> <ActionContext.Provider value={{ visible, setVisible }}>
@ -170,7 +202,7 @@ export const AddFieldAction = (props) => {
} }
}} }}
> >
{getOptions().map((option) => { {getFieldOptions().map((option) => {
return ( return (
option.children.length > 0 && ( option.children.length > 0 && (
<Menu.ItemGroup key={option.label} title={compile(option.label)}> <Menu.ItemGroup key={option.label} title={compile(option.label)}>

View File

@ -1,13 +1,12 @@
import { useForm } from '@formily/react'; import { useForm } from '@formily/react';
import { action } from '@formily/reactive'; import { action } from '@formily/reactive';
import { uid } from '@formily/shared'; import { uid } from '@formily/shared';
import React, { useContext, useEffect, useRef, useState } from 'react'; import React, { useContext, useRef, useState } from 'react';
import { CollectionFieldsTable } from '.'; import { CollectionFieldsTable } from '.';
import { useRequest } from '../../api-client';
import { useCurrentAppInfo } from '../../appInfo'; import { useCurrentAppInfo } from '../../appInfo';
import { useRecord } from '../../record-provider'; import { useRecord } from '../../record-provider';
import { SchemaComponent, SchemaComponentContext, useActionContext, useCompile } from '../../schema-component'; import { SchemaComponent, SchemaComponentContext, useCompile } from '../../schema-component';
import { useCancelAction, useUpdateCollectionActionAndRefreshCM } from '../action-hooks'; import { useCancelAction } from '../action-hooks';
import { useCollectionManager } from '../hooks/useCollectionManager'; import { useCollectionManager } from '../hooks/useCollectionManager';
import { DataSourceContext } from '../sub-table'; import { DataSourceContext } from '../sub-table';
import { AddSubFieldAction } from './AddSubFieldAction'; import { AddSubFieldAction } from './AddSubFieldAction';
@ -25,109 +24,6 @@ const useAsyncDataSource = (service: any) => (field: any) => {
); );
}; };
const useCollectionValues = (options) => {
const { visible } = useActionContext();
const result = useRequest(
() =>
Promise.resolve({
data: {
name: `t_${uid()}`,
createdBy: true,
updatedBy: true,
sortable: true,
logging: true,
fields: [
{
name: 'id',
type: 'bigInt',
autoIncrement: true,
primaryKey: true,
allowNull: false,
uiSchema: { type: 'number', title: '{{t("ID")}}', 'x-component': 'InputNumber', 'x-read-pretty': true },
interface: 'id',
},
{
interface: 'createdAt',
type: 'date',
field: 'createdAt',
name: 'createdAt',
uiSchema: {
type: 'datetime',
title: '{{t("Created at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
interface: 'createdBy',
type: 'belongsTo',
target: 'users',
foreignKey: 'createdById',
name: 'createdBy',
uiSchema: {
type: 'object',
title: '{{t("Created by")}}',
'x-component': 'RecordPicker',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
},
{
type: 'date',
field: 'updatedAt',
name: 'updatedAt',
interface: 'updatedAt',
uiSchema: {
type: 'string',
title: '{{t("Last updated at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
type: 'belongsTo',
target: 'users',
foreignKey: 'updatedById',
name: 'updatedBy',
interface: 'updatedBy',
uiSchema: {
type: 'object',
title: '{{t("Last updated by")}}',
'x-component': 'RecordPicker',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
},
],
},
}),
{
...options,
manual: true,
},
);
useEffect(() => {
if (visible) {
result.run();
}
}, [visible]);
return result;
};
const useSelectedRowKeys = () => { const useSelectedRowKeys = () => {
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]);
return [selectedRowKeys, setSelectedRowKeys]; return [selectedRowKeys, setSelectedRowKeys];
@ -205,13 +101,11 @@ export const ConfigurationTable = () => {
useDestroySubField, useDestroySubField,
useBulkDestroySubField, useBulkDestroySubField,
useSelectedRowKeys, useSelectedRowKeys,
useCollectionValues,
useAsyncDataSource, useAsyncDataSource,
loadCollections, loadCollections,
useCurrentFields, useCurrentFields,
useNewId, useNewId,
useCancelAction, useCancelAction,
useUpdateCollectionActionAndRefreshCM,
enableInherits: database?.dialect === 'postgres', enableInherits: database?.dialect === 'postgres',
}} }}
/> />

View File

@ -0,0 +1,161 @@
import { ArrayTable } from '@formily/antd';
import { ISchema, useForm } from '@formily/react';
import { uid } from '@formily/shared';
import { omit } from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useRequest } from '../../api-client';
import { RecordProvider, useRecord } from '../../record-provider';
import { ActionContext, SchemaComponent, useActionContext, useCompile } from '../../schema-component';
import { useCancelAction } from '../action-hooks';
import { useCollectionManager } from '../hooks';
import { IField } from '../interfaces/types';
import { useResourceActionContext, useResourceContext } from '../ResourceActionProvider';
import * as components from './components';
const getSchema = (schema: IField, record: any, compile, getContainer): ISchema => {
if (!schema) {
return;
}
const properties = (cloneDeep(schema.configurableProperties) as any) || {
title: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
name: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-disabled': true,
},
};
properties.name['x-disabled'] = true;
if (schema.hasDefaultValue === true) {
properties['defaultValue'] = cloneDeep(schema.default.uiSchema);
properties['defaultValue']['title'] = compile('{{ t("Default value") }}');
properties['defaultValue']['x-decorator'] = 'FormItem';
}
return {
type: 'object',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues: '{{ useValuesFromRecord }}',
},
title: '{{ t("Edit collection") }}',
properties: {
...properties,
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: '{{ t("Cancel") }}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ useCancelAction }}',
},
},
action2: {
title: '{{ t("Submit") }}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ useUpdateCollectionActionAndRefreshCM }}',
},
},
},
},
},
},
},
};
};
export const useValuesFromRecord = (options) => {
const record = useRecord();
const result = useRequest(() => Promise.resolve({ data: { autoGenId: true, ...record } }), {
...options,
manual: true,
});
const ctx = useActionContext();
useEffect(() => {
if (ctx.visible) {
result.run();
}
}, [ctx.visible]);
return result;
};
export const useUpdateCollectionActionAndRefreshCM = (options) => {
const { refreshCM } = useCollectionManager();
const form = useForm();
const ctx = useActionContext();
const { refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
const { [targetKey]: filterByTk } = useRecord();
return {
async run() {
await form.submit();
await resource.update({ filterByTk, values: omit(form.values, ['fields']) });
ctx.setVisible(false);
await form.reset();
refresh();
await refreshCM();
},
};
};
export const EditCollection = (props) => {
const record = useRecord();
return <EditCollectionAction item={record} {...props} />;
};
export const EditCollectionAction = (props) => {
const { scope, getContainer, item: record, children } = props;
const { getTemplate } = useCollectionManager();
const [visible, setVisible] = useState(false);
const [schema, setSchema] = useState({});
const { t } = useTranslation();
const compile = useCompile();
return (
<RecordProvider record={record}>
<ActionContext.Provider value={{ visible, setVisible }}>
<a
onClick={async () => {
const templateConf = getTemplate(record.template);
const schema = getSchema(
{
...templateConf,
},
record,
compile,
getContainer,
);
setSchema(schema);
setVisible(true);
}}
>
{children || t('Edit')}
</a>
<SchemaComponent
schema={schema}
components={{ ...components, ArrayTable }}
scope={{
getContainer,
useValuesFromRecord,
useUpdateCollectionActionAndRefreshCM,
useCancelAction,
createOnly: false,
...scope,
}}
/>
</ActionContext.Provider>
</RecordProvider>
);
};

View File

@ -0,0 +1,14 @@
import { observer } from '@formily/react';
import { Tag } from 'antd';
import React from 'react';
import { useCompile } from '../../../schema-component';
import { useCollectionManager } from '../../hooks';
export const CollectionTemplate = observer((props: any) => {
const { value } = props;
const { getTemplate } = useCollectionManager();
const compile = useCompile();
const schema = getTemplate(value);
return <Tag>{compile(schema?.title||'{{t("General collection")}}')}</Tag>;
});

View File

@ -1,15 +1,17 @@
import { registerValidateFormats } from '@formily/core'; import { registerValidateFormats } from '@formily/core';
import { exp } from 'mathjs';
export * from './AddFieldAction'; export * from './AddFieldAction';
export * from './ConfigurationTable'; export * from './ConfigurationTable';
export * from './EditFieldAction'; export * from './EditFieldAction';
export * from './interfaces'; export * from './interfaces';
export * from './components'; export * from './components';
export * from './templates';
export * from './CollectionFieldsTable'; export * from './CollectionFieldsTable';
export * from './schemas/collections' export * from './schemas/collections';
export * from './OverridingCollectionField' export * from './OverridingCollectionField';
export * from './ViewInheritedField' export * from './ViewInheritedField';
export * from './AddCollectionAction';
export * from './EditCollectionAction';
registerValidateFormats({ registerValidateFormats({
uid: /^[A-Za-z0-9][A-Za-z0-9_-]*$/, uid: /^[A-Za-z0-9][A-Za-z0-9_-]*$/,

View File

@ -35,6 +35,7 @@ export const getOptions = () => {
return Object.keys(groupLabels).map((groupName) => { return Object.keys(groupLabels).map((groupName) => {
return { return {
label: groupLabels[groupName], label: groupLabels[groupName],
key: groupName,
children: Object.keys(fields[groupName] || {}) children: Object.keys(fields[groupName] || {})
.map((type) => { .map((type) => {
const field = fields[groupName][type]; const field = fields[groupName][type];

View File

@ -1,6 +1,7 @@
import { ISchema, Schema } from '@formily/react'; import { ISchema, Schema } from '@formily/react';
import { i18n } from '../../../i18n'; import { i18n } from '../../../i18n';
import { CollectionOptions } from '../../types'; import { CollectionOptions } from '../../types';
import { CollectionTemplate } from '../components/CollectionTemplate';
import { collectionFieldSchema } from './collectionFields'; import { collectionFieldSchema } from './collectionFields';
const compile = (source) => { const compile = (source) => {
@ -35,6 +36,16 @@ export const collection: CollectionOptions = {
'{{t("Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.")}}', '{{t("Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.")}}',
}, },
}, },
{
type: 'string',
name: 'template',
interface: 'input',
uiSchema: {
title: '{{ t("Collection Template") }}',
type: 'string',
'x-component': 'Input',
},
},
{ {
type: 'hasMany', type: 'hasMany',
name: 'fields', name: 'fields',
@ -60,85 +71,6 @@ export const collection: CollectionOptions = {
], ],
}; };
export const createCollectionProperties = {
title: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
name: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-validator': 'uid',
},
inherits: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-visible': '{{ enableInherits}}',
'x-reactions': ['{{useAsyncDataSource(loadCollections)}}'],
},
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: '{{ t("Cancel") }}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ cm.useCancelAction }}',
},
},
action2: {
title: '{{ t("Submit") }}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ cm.useCreateActionAndRefreshCM }}',
},
},
},
},
};
export const editCollectionProperties = {
title: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
name: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-disabled': true,
},
inherits: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-disabled': true,
'x-visible': '{{ enableInherits}}',
'x-reactions': ['{{useAsyncDataSource(loadCollections)}}'],
},
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: '{{ t("Cancel") }}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ useCancelAction }}',
},
},
action2: {
title: '{{ t("Submit") }}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ useUpdateCollectionActionAndRefreshCM }}',
},
},
},
},
};
export const collectionSchema: ISchema = { export const collectionSchema: ISchema = {
type: 'object', type: 'object',
properties: { properties: {
@ -190,6 +122,7 @@ export const collectionSchema: ISchema = {
title: '{{ t("Delete") }}', title: '{{ t("Delete") }}',
'x-component': 'Action', 'x-component': 'Action',
'x-component-props': { 'x-component-props': {
icon: 'DeleteOutlined',
useAction: '{{ cm.useBulkDestroyActionAndRefreshCM }}', useAction: '{{ cm.useBulkDestroyActionAndRefreshCM }}',
confirm: { confirm: {
title: "{{t('Delete record')}}", title: "{{t('Delete record')}}",
@ -200,22 +133,10 @@ export const collectionSchema: ISchema = {
create: { create: {
type: 'void', type: 'void',
title: '{{ t("Create collection") }}', title: '{{ t("Create collection") }}',
'x-component': 'Action', 'x-component': 'AddCollection',
'x-component-props': { 'x-component-props': {
type: 'primary', type: 'primary',
}, },
properties: {
drawer: {
type: 'void',
title: '{{ t("Create collection") }}',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues: '{{ useCollectionValues }}',
},
properties: createCollectionProperties,
},
},
}, },
}, },
}, },
@ -255,6 +176,18 @@ export const collectionSchema: ISchema = {
}, },
}, },
column3: { column3: {
type: 'void',
'x-decorator': 'Table.Column.Decorator',
'x-component': 'Table.Column',
title: '{{t("Collection template")}}',
properties: {
template: {
'x-component': CollectionTemplate,
'x-read-pretty': true,
},
},
},
column4: {
type: 'void', type: 'void',
title: '{{ t("Actions") }}', title: '{{ t("Actions") }}',
'x-component': 'Table.Column', 'x-component': 'Table.Column',
@ -294,22 +227,10 @@ export const collectionSchema: ISchema = {
update: { update: {
type: 'void', type: 'void',
title: '{{ t("Edit") }}', title: '{{ t("Edit") }}',
'x-component': 'Action.Link', 'x-component': 'EditCollection',
'x-component-props': { 'x-component-props': {
type: 'primary', type: 'primary',
}, },
properties: {
drawer: {
type: 'void',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues: '{{ cm.useValuesFromRecord }}',
},
title: '{{ t("Edit collection") }}',
properties: editCollectionProperties,
},
},
}, },
delete: { delete: {
type: 'void', type: 'void',

View File

@ -0,0 +1,23 @@
import { ISchema } from '@formily/react';
import * as types from '../templates';
export const templates = new Map<string, ISchema>();
const collectionTemplates: any = {};
export function registerTemplate(key: string, schema: any) {
collectionTemplates[key] = schema;
}
Object.keys(types).forEach((type) => {
const schema = types[type];
registerTemplate(schema.name || 'others', { order: 0, ...schema });
});
export const templateOptions = () =>
Object.keys(collectionTemplates)
.sort((a, b) => {
return collectionTemplates[a].order - collectionTemplates[b].order;
})
.map((templace) => {
return collectionTemplates[templace];
});

View File

@ -259,39 +259,6 @@ export const useBulkDestroyAction = () => {
}; };
}; };
export const useUpdateCollectionActionAndRefreshCM = (options) => {
const { refreshCM } = useCollectionManager();
const form = useForm();
const ctx = useActionContext();
const { refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
const { [targetKey]: filterByTk } = useRecord();
return {
async run() {
await form.submit();
await resource.update({ filterByTk, values: omit(form.values, ['fields']) });
ctx.setVisible(false);
await form.reset();
refresh();
await refreshCM();
},
};
};
export const useValuesFromRecord = (options) => {
const record = useRecord();
const result = useRequest(() => Promise.resolve({ data: record }), {
...options,
manual: true,
});
const ctx = useActionContext();
useEffect(() => {
if (ctx.visible) {
result.run();
}
}, [ctx.visible]);
return result;
};
export const useValuesFromRA = (options) => { export const useValuesFromRA = (options) => {
const ctx = useResourceActionContext(); const ctx = useResourceActionContext();

View File

@ -1,11 +1,11 @@
import { clone } from '@formily/shared'; import { clone } from '@formily/shared';
import { useContext } from 'react';
import { reduce, unionBy, uniq } from 'lodash'; import { reduce, unionBy, uniq } from 'lodash';
import { useContext } from 'react';
import { CollectionManagerContext } from '../context'; import { CollectionManagerContext } from '../context';
import { CollectionFieldOptions } from '../types'; import { CollectionFieldOptions } from '../types';
export const useCollectionManager = () => { export const useCollectionManager = () => {
const { refreshCM, service, interfaces, collections } = useContext(CollectionManagerContext); const { refreshCM, service, interfaces, collections, templates } = useContext(CollectionManagerContext);
const getInheritedFields = (name) => { const getInheritedFields = (name) => {
const inheritKeys = getInheritCollections(name); const inheritKeys = getInheritCollections(name);
const inheritedFields = reduce( const inheritedFields = reduce(
@ -122,6 +122,9 @@ export const useCollectionManager = () => {
getInterface(name: string) { getInterface(name: string) {
return interfaces[name] ? clone(interfaces[name]) : null; return interfaces[name] ? clone(interfaces[name]) : null;
}, },
getTemplate(name: string = 'general') {
return templates[name] ? clone(templates[name] || templates['general']) : null;
},
getParentCollectionFields: (parentCollection, currentCollection) => { getParentCollectionFields: (parentCollection, currentCollection) => {
const currentFields = collections?.find((collection) => collection.name === currentCollection)?.fields; const currentFields = collections?.find((collection) => collection.name === currentCollection)?.fields;
const parentFields = collections?.find((collection) => collection.name === parentCollection)?.fields; const parentFields = collections?.find((collection) => collection.name === parentCollection)?.fields;

View File

@ -12,5 +12,7 @@ export * from './hooks';
export * as interfacesProperties from './interfaces/properties'; export * as interfacesProperties from './interfaces/properties';
export * from './interfaces/types'; export * from './interfaces/types';
export * from './ResourceActionProvider'; export * from './ResourceActionProvider';
export { getConfigurableProperties } from './templates/properties';
export * from './templates/types';
export * from './types'; export * from './types';

View File

@ -60,6 +60,7 @@ export const constraintsProps = {
title: '{{t("ON DELETE")}}', title: '{{t("ON DELETE")}}',
required: true, required: true,
default: 'SET NULL', default: 'SET NULL',
'x-disabled': '{{ !createOnly }}',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-component': 'Select', 'x-component': 'Select',
enum: [ enum: [

View File

@ -0,0 +1,37 @@
import { getConfigurableProperties } from './properties';
import { ICollectionTemplate } from './types';
export const calendar: ICollectionTemplate = {
name: 'calendar',
title: '{{t("Calendar collection")}}',
order: 2,
color: 'orange',
default: {
fields: [
{
name: 'cron',
type: 'string',
uiSchema: {
type: 'string',
title: '{{t("Cron")}}',
'x-component': 'Select',
enum: [
{ value: '0 0 * * *', label: '每天' },
{ value: '0 0 ? * 1', label: '每个星期一' },
{ value: '0 0 12 * * ?', label: '每天中午12点' },
{ value: '0 0 10,14,16 * * ?', label: '每天上午10点,下午2点,4点 ' },
],
},
interface: 'select',
},
{
name: 'exclude',
type: 'json',
},
],
},
availableFieldInterfaces: {
include: [],
},
configurableProperties: getConfigurableProperties('title', 'name', 'inherits'),
};

View File

@ -0,0 +1,23 @@
import { getConfigurableProperties } from './properties';
import { ICollectionTemplate } from './types';
export const general: ICollectionTemplate = {
name: 'general',
title: '{{t("General collection")}}',
order: 1,
color: 'blue',
default: {
fields: [],
},
configurableProperties: getConfigurableProperties(
'title',
'name',
'inherits',
'autoGenId',
'createdAt',
'updatedAt',
'createdBy',
'updatedBy',
'sortable',
),
};

View File

@ -0,0 +1,3 @@
export * from './calendar';
export * from './general';

View File

@ -0,0 +1,121 @@
export const defaultConfigurableProperties = {
title: {
type: 'string',
title: '{{ t("Collection display name") }}',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
name: {
type: 'string',
title: '{{t("Collection name")}}',
required: true,
'x-disabled': '{{ !createOnly }}',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-validator': 'uid',
description:
"{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}",
},
inherits: {
title: '{{t("Inherits")}}',
type: 'hasMany',
name: 'inherits',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
mode: 'multiple',
},
'x-disabled': '{{ !createOnly }}',
'x-visible': '{{ enableInherits}}',
'x-reactions': ['{{useAsyncDataSource(loadCollections)}}'],
},
autoGenId: {
type: 'boolean',
'x-content': '{{t("AutoGenId")}}',
default: true,
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createOnly }}',
'x-reactions': [
{
target: 'sortable',
when: '{{createOnly&&!$self.value}}',
fulfill: {
state: {
value: false,
},
schema: {
'x-disabled': true,
},
},
otherwise: {
schema: {
'x-disabled': '{{!createOnly}}',
},
},
},
],
},
createdBy: {
type: 'boolean',
'x-content': '{{t("CreatedBy")}}',
default: true,
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createOnly }}',
},
updatedBy: {
type: 'boolean',
'x-content': '{{t("UpdatedBy")}}',
default: true,
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createOnly }}',
},
createdAt: {
type: 'boolean',
'x-content': '{{t("CreatedAt")}}',
default: true,
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createOnly }}',
},
updatedAt: {
type: 'boolean',
'x-content': '{{t("UpdatedAt")}}',
default: true,
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createOnly }}',
},
sortable: {
type: 'boolean',
'x-content': '{{t("Records can be sorted")}}',
default: true,
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createOnly }}',
},
};
export type DefaultConfigurableKeys =
| 'name'
| 'title'
| 'inherits'
| 'autoGenId'
| 'createdBy'
| 'updatedBy'
| 'createdAt'
| 'updatedAt'
| 'sortable';
export const getConfigurableProperties = (...keys: DefaultConfigurableKeys[]) => {
const props = {};
for (const key of keys) {
if (defaultConfigurableProperties[key]) {
props[key] = defaultConfigurableProperties[key];
}
}
return props;
};

View File

@ -0,0 +1,52 @@
import { ISchema } from '@formily/react';
import { FieldOptions } from '../../collection-manager/types';
export interface ICollectionTemplate {
name: string;
title?: string;
color?:string;
/** 排序 */
order?: number;
/** 默认配置 */
default?: CollectionOptions;
/** UI 可配置的 CollectionOptions 参数(添加或编辑的 Collection 表单的字段) */
configurableProperties?: Record<string, ISchema>;
/** 当前模板可用的字段类型 */
availableFieldInterfaces?: AvailableFieldInterfacesInclude | AvailableFieldInterfacesExclude;
}
interface AvailableFieldInterfacesInclude {
include?: any[];
}
interface AvailableFieldInterfacesExclude {
exclude?: any[];
}
interface CollectionOptions {
/**
* id
* @default true
* */
autoGenId?: boolean;
/** 创建人 */
createdBy?: boolean;
/** 最后更新人 */
updatedBy?: boolean;
/** 创建日期 */
createdAt?: boolean;
/** 更新日期 */
updatedAt?: boolean;
/** 可排序 */
sortable?: boolean;
/* 树结构 */
tree?: string;
/* 日志 */
logging?: boolean;
/** 继承 */
inherits?: string | string[];
/* 字段列表 */
fields?: FieldOptions[];
}

View File

@ -4,6 +4,7 @@ export interface CollectionManagerOptions {
service?: any; service?: any;
interfaces?: any; interfaces?: any;
collections?: any[]; collections?: any[];
templates?: any;
refreshCM?: () => Promise<void>; refreshCM?: () => Promise<void>;
} }

View File

@ -114,6 +114,15 @@ export default {
"Collection display name": "Collection display name", "Collection display name": "Collection display name",
"Collection name": "Collection name", "Collection name": "Collection name",
"Inherits":"Inherits", "Inherits":"Inherits",
"AutoGenId":"Auto-generated ID field",
"CreatedBy":"Recording a row's created user",
"UpdatedBy":"Recording a row's last updated user",
"CreatedAt":"Recording a row's created time ",
"UpdatedAt":"Recording a row's last updated user",
"Records can be sorted": "Records can be sorted",
"Collection template":"Collection template",
"Calendar collection":"Calendar collection",
"General collection":"General collection",
"Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.", "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.",
"Storage type": "Storage type", "Storage type": "Storage type",
"Edit": "Edit", "Edit": "Edit",

View File

@ -107,6 +107,16 @@ export default {
"Create collection": "コレクションの作成", "Create collection": "コレクションの作成",
"Collection display name": "コレクション名", "Collection display name": "コレクション名",
"Collection name": "コレクション識別子", "Collection name": "コレクション識別子",
"Inherits":"継承",
"AutoGenId":"IDフィールドの自動生成",
"CreatedBy":"レコード作成者",
"UpdatedBy":"レコード最終更新者",
"CreatedAt":"レコード作成時間",
"UpdatedAt":"レコード最終更新時間",
"Records can be sorted":"ソート可能",
"Collection template":"データテーブルテンプレート",
"Calendar collection":"カレンダデータテーブル",
"General collection":"一般データテーブル",
"Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "ランダムに生成され、変更可能です。 アルファベット、数字、アンダースコアをサポートし、アルファベットから始まる必要があります。", "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "ランダムに生成され、変更可能です。 アルファベット、数字、アンダースコアをサポートし、アルファベットから始まる必要があります。",
"Storage type": "ストレージタイプ", "Storage type": "ストレージタイプ",
"Edit": "編集", "Edit": "編集",
@ -503,6 +513,5 @@ export default {
"Format": "フォーマット", "Format": "フォーマット",
"Error message": "エラーメッセージ", "Error message": "エラーメッセージ",
"Record picker": "レコードピッカー", "Record picker": "レコードピッカー",
"Sortable": "ソート可能",
"Search and select collection": "Search and select collection", "Search and select collection": "Search and select collection",
} }

View File

@ -118,6 +118,15 @@ export default {
"Collection display name": "数据表名称", "Collection display name": "数据表名称",
"Collection name": "数据表标识", "Collection name": "数据表标识",
"Inherits":"继承", "Inherits":"继承",
"AutoGenId":"自动生成 ID 字段",
"CreatedBy":"记录创建人",
"UpdatedBy":"记录最后更新人",
"CreatedAt":"记录创建时间",
"UpdatedAt":"记录最后更新时间",
"Records can be sorted":"可以对行记录进行排序",
"Collection template":"数据表模板",
"Calendar collection":"日历数据表",
"General collection":"普通数据表",
"Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "随机生成,可修改。支持英文、数字和下划线,必须以英文字母开头。", "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "随机生成,可修改。支持英文、数字和下划线,必须以英文字母开头。",
"Storage type": "存储类型", "Storage type": "存储类型",
"Edit": "编辑", "Edit": "编辑",
@ -228,7 +237,6 @@ export default {
"Editable": "可编辑", "Editable": "可编辑",
"Readonly": "只读(禁止编辑)", "Readonly": "只读(禁止编辑)",
"Easy-reading": "只读(阅读模式)", "Easy-reading": "只读(阅读模式)",
"Sortable": "可排序",
"Add filter": "添加筛选条件", "Add filter": "添加筛选条件",
"Add filter group": "添加筛选分组", "Add filter group": "添加筛选分组",
"Comparision": "值比较", "Comparision": "值比较",

View File

@ -37,7 +37,7 @@ export const TableBlockDesigner = () => {
return ( return (
<GeneralSchemaDesigner template={template} title={title || name}> <GeneralSchemaDesigner template={template} title={title || name}>
<SchemaSettings.BlockTitleItem /> <SchemaSettings.BlockTitleItem />
<SchemaSettings.SwitchItem {sortable&& <SchemaSettings.SwitchItem
title={t('Enable drag and drop sorting')} title={t('Enable drag and drop sorting')}
checked={field.decoratorProps.dragSort} checked={field.decoratorProps.dragSort}
onChange={(dragSort) => { onChange={(dragSort) => {
@ -51,7 +51,7 @@ export const TableBlockDesigner = () => {
}, },
}); });
}} }}
/> />}
<SchemaSettings.ModalItem <SchemaSettings.ModalItem
title={t('Set the data scope')} title={t('Set the data scope')}
schema={ schema={

View File

@ -524,6 +524,8 @@ export const useCollectionDataSourceItems = (componentName) => {
const b = !value || selected.includes(item.name); const b = !value || selected.includes(item.name);
if (item.inherit) { if (item.inherit) {
return false; return false;
} else if (!item.fields.find((v) => v.primaryKey)) {
return false;
} else { } else {
return b && !(item?.isThrough && item?.autoCreate); return b && !(item?.isThrough && item?.autoCreate);
} }

View File

@ -105,6 +105,15 @@ class AppGenerator extends Generator {
break; break;
} }
const keys = ['PLUGIN_PACKAGE_PREFIX', 'DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD', 'DB_STORAGE'];
for (const key in env) {
if (keys.includes(key)) {
continue;
}
envs.push(`${key}=${env[key]}`);
}
return { return {
...this.context, ...this.context,
dependencies: dependencies.join(`,\n `), dependencies: dependencies.join(`,\n `),

View File

@ -3,7 +3,9 @@ import path from 'path';
export class PresetNocoBase extends Plugin { export class PresetNocoBase extends Plugin {
async addBuiltInPlugins() { async addBuiltInPlugins() {
const plugins = [ const plugins = process.env.PRESET_NOCOBASE_PLUGINS
? process.env.PRESET_NOCOBASE_PLUGINS.split(',')
: [
'error-handler', 'error-handler',
'collection-manager', 'collection-manager',
'ui-schema-storage', 'ui-schema-storage',

@ -1 +1 @@
Subproject commit 5a5fba41ae1cecaf3b073fcb610e9dc68dad0b85 Subproject commit 67f51c7fdd132ab12821f31f737b6f0cfb70d212

View File

@ -0,0 +1,28 @@
# custom-collection-template
## Register
```ts
yarn pm add sample-custom-collection-template
```
## Activate
```bash
yarn pm enable sample-custom-collection-template
```
## Launch the app
```bash
# for development
yarn dev
# for production
yarn build
yarn start
```
## Demo
[gif]

View File

@ -0,0 +1,4 @@
// @ts-nocheck
export * from './lib/client';
export { default } from './lib/client';

View File

@ -0,0 +1,30 @@
"use strict";
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var _index = _interopRequireWildcard(require("./lib/client"));
Object.defineProperty(exports, "__esModule", {
value: true
});
var _exportNames = {};
Object.defineProperty(exports, "default", {
enumerable: true,
get: function get() {
return _index.default;
}
});
Object.keys(_index).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
if (key in exports && exports[key] === _index[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _index[key];
}
});
});

View File

@ -0,0 +1,11 @@
{
"name": "@nocobase/plugin-sample-custom-collection-template",
"version": "0.8.0-alpha.13",
"main": "lib/server/index.js",
"devDependencies": {
"@nocobase/client": "0.8.0-alpha.13",
"@nocobase/server": "0.8.0-alpha.13",
"@nocobase/test": "0.8.0-alpha.13"
},
"gitHead": "ce588eefb0bfc50f7d5bbee575e0b5e843bf6644"
}

View File

@ -0,0 +1,31 @@
import { getConfigurableProperties, ICollectionTemplate, registerTemplate } from '@nocobase/client';
import React from 'react';
const myCollectionTemplate: ICollectionTemplate = {
name: 'myCollection',
title: '{{t("Custom template")}}',
order: 6,
color: 'blue',
default: {
fields: [
{
name: 'uuid',
type: 'string',
primaryKey: true,
allowNull: false,
uiSchema: { type: 'number', title: '{{t("UUID")}}', 'x-component': 'Input', 'x-read-pretty': true },
interface: 'input',
},
],
},
configurableProperties: getConfigurableProperties('name', 'title', 'inherits', 'createdAt', 'updatedAt'),
availableFieldInterfaces: {
exclude: ['linkTo', 'o2o'],
},
};
registerTemplate('myCollection', myCollectionTemplate);
export default React.memo((props) => {
return <>{props.children}</>;
});

View File

@ -0,0 +1 @@
export { default } from './server';

View File

@ -0,0 +1,16 @@
import { InstallOptions, Plugin } from '@nocobase/server';
export class CustomCollectionTemplatePlugin extends Plugin {
afterAdd() {}
beforeLoad() {}
async load() {}
async install(options: InstallOptions) {
// TODO
}
}
export default CustomCollectionTemplatePlugin;

337
yarn.lock
View File

@ -329,23 +329,6 @@
csstype "^3.0.8" csstype "^3.0.8"
tslib "^2.0.3" tslib "^2.0.3"
"@antv/x6-react-shape@^1.6.2":
version "1.6.3"
resolved "https://registry.yarnpkg.com/@antv/x6-react-shape/-/x6-react-shape-1.6.3.tgz#053660bd555c4356e9719134e3e2a857b51301e2"
integrity sha512-iCsRVkvKCVs7HUUblF/ALg5XxeeEPXDLHuYzRvbvNlCKKLbXLbaz6vJQSgTTrk2i4lrD+7xl4riA76FyWA3k/g==
"@antv/x6@^1.34.2":
version "1.34.6"
resolved "https://registry.yarnpkg.com/@antv/x6/-/x6-1.34.6.tgz#b802b09b52c8620acf01734397714ea5e3f715b6"
integrity sha512-cl8ywN7CTNVT94/ZEbq2mnZQTQe6FUgIlGOAjNOPL8sljZTBrpE6OsuGw4BDA2/XllwELfUfvVpgBvbdwRKrxw==
dependencies:
csstype "^3.0.3"
jquery "^3.5.1"
jquery-mousewheel "^3.1.13"
lodash-es "^4.17.15"
mousetrap "^1.6.5"
utility-types "^3.10.0"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0": "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0":
version "7.16.0" version "7.16.0"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
@ -2969,15 +2952,6 @@
resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz#c3c5ae543c897caa9c2a68630bed355be5f9990f" resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz#c3c5ae543c897caa9c2a68630bed355be5f9990f"
integrity sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ== integrity sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==
"@dabh/diagnostics@^2.0.2":
version "2.0.3"
resolved "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==
dependencies:
colorspace "1.1.x"
enabled "2.0.x"
kuler "^2.0.0"
"@dnd-kit/accessibility@^3.0.0": "@dnd-kit/accessibility@^3.0.0":
version "3.0.0" version "3.0.0"
resolved "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz#b56e3750414fd907b7d6972b3116aa8f96d07fde" resolved "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz#b56e3750414fd907b7d6972b3116aa8f96d07fde"
@ -4383,153 +4357,6 @@
call-me-maybe "^1.0.1" call-me-maybe "^1.0.1"
glob-to-regexp "^0.3.0" glob-to-regexp "^0.3.0"
"@nocobase/acl@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/acl/-/acl-0.8.0-alpha.9.tgz#7ffab4a367befc74daa681b1d5c2c907126cb280"
integrity sha512-jEgpjO6gGi4GwSyWxlmcwd368/AQgmrdsODDTLhhrJJI9+ovj2mxO664lQgh3FkDGtmduKlBiZ+qcgK+/RWa1w==
dependencies:
"@nocobase/resourcer" "0.8.0-alpha.9"
json-templates "^4.2.0"
"@nocobase/actions@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/actions/-/actions-0.8.0-alpha.9.tgz#3804bbf30f7c4e8aa205b9802ec4f56a58c18c72"
integrity sha512-EvdNjXa+TTMU2Xn+MnA7tSa5rooGFtzsvJsSYbkpODtsVQsmTDRIZYZsOYFk/XcezxjzTTsxxXMSA7sLq6wifQ==
dependencies:
"@nocobase/cache" "0.8.0-alpha.9"
"@nocobase/database" "0.8.0-alpha.9"
"@nocobase/resourcer" "0.8.0-alpha.9"
"@nocobase/cache@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/cache/-/cache-0.8.0-alpha.9.tgz#99f7ca196dacd41b69ed7b7f179fcc1c4c5baa27"
integrity sha512-GCi7OE9nLrXKq/Og6SPtPcjtreUxxAL9x7CwmD2x3Zb7gNTc2GvQ9NWoAlO8KTLlWuzuNcJXegBhxaxV8Lt5ew==
dependencies:
cache-manager "^4.1.0"
"@nocobase/client@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/client/-/client-0.8.0-alpha.9.tgz#03446b4c4160a7ebda9dfd8aa80e2203541eb72c"
integrity sha512-cvh01k8Ujhc9D7kDYQ7QKP5tnLF+wBOqixtisivti9aeklMBaOKj1oLmxKHZlB2IJzKpT+rUntpsxGxUS6co9A==
dependencies:
"@antv/g2plot" "^2.4.18"
"@dnd-kit/core" "^5.0.1"
"@dnd-kit/sortable" "^6.0.0"
"@emotion/css" "^11.7.1"
"@formily/antd" "2.0.20"
"@formily/core" "2.0.20"
"@formily/react" "2.0.20"
"@nocobase/sdk" "0.8.0-alpha.9"
"@nocobase/utils" "0.8.0-alpha.9"
ahooks "^3.0.5"
antd "~4.19.5"
axios "^0.26.1"
classnames "^2.3.1"
cron-parser "^4.6.0"
cronstrue "^2.11.0"
file-saver "^2.0.5"
i18next "^21.6.0"
json-templates "^4.2.0"
marked "^4.0.12"
mathjs "^10.6.0"
react-beautiful-dnd "^13.1.0"
react-big-calendar "^0.38.7"
react-contenteditable "^3.3.6"
react-drag-listview "^0.1.9"
react-helmet "^6.1.0"
react-hotkeys-hook "^3.4.7"
react-i18next "^11.15.1"
react-image-lightbox "^5.1.4"
react-js-cron "^1.4.0"
react-quill "^1.3.5"
react-router-dom "^5.2.0"
react-to-print "^2.14.7"
solarlunar-es "^1.0.9"
use-deep-compare-effect "^1.8.1"
"@nocobase/database@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/database/-/database-0.8.0-alpha.9.tgz#9684b4ddcfc5396df2ef3d4ae9cd2ce59142df81"
integrity sha512-zkLTW2iFg1tlbSTlW40oEmM7O2GxHXmIzErnDR4it0GWoLqjDgzNHP5QjODOxiiB/+/unNFudfGTNCoXxu2ZvA==
dependencies:
"@nocobase/utils" "0.8.0-alpha.9"
async-mutex "^0.3.2"
cron-parser "4.4.0"
deepmerge "^4.2.2"
flat "^5.0.2"
glob "^7.1.6"
mathjs "^10.6.1"
moment "2.x"
semver "^7.3.7"
sequelize "^6.9.0"
umzug "^3.1.1"
"@nocobase/resourcer@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/resourcer/-/resourcer-0.8.0-alpha.9.tgz#5415af5944b31293e5e2da73bf5c999866a90fab"
integrity sha512-6v9bfUex2RfT8C3xX+SUhj8/zECCY6pQA3ce8GV3xd9cu6ku8c7hIiNM3KwgPOD189aND3FxNwxqpECNaoWQ1A==
dependencies:
"@nocobase/utils" "0.8.0-alpha.9"
deepmerge "^4.2.2"
koa-compose "^4.1.0"
lodash "^4.17.21"
path-to-regexp "^6.1.0"
qs "^6.9.4"
"@nocobase/sdk@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/sdk/-/sdk-0.8.0-alpha.9.tgz#5306e7bf4aabf00894a65036c584508d93bda379"
integrity sha512-v+GF4N5ldYwmoqQIukGWzz/eOm2TgxcUZq3uE+YeP/aiDa4XAfkLrpBNsvCS24k3s/U+84FYrvTWRRStJGSzBA==
dependencies:
axios "^0.26.1"
qs "^6.10.1"
"@nocobase/server@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/server/-/server-0.8.0-alpha.9.tgz#bc1955e41b2ac9f6640fdf109516376604d4092c"
integrity sha512-/mHk2Uc8RS/3GcGvnMnFKlbf2aCufGuc+GOr5gEKuyWa50ibD4nZ7LKJx023uEO07rxWkFkhR6+ExuZ+BGRDGQ==
dependencies:
"@hapi/topo" "^6.0.0"
"@koa/cors" "^3.1.0"
"@koa/router" "^9.4.0"
"@nocobase/acl" "0.8.0-alpha.9"
"@nocobase/actions" "0.8.0-alpha.9"
"@nocobase/database" "0.8.0-alpha.9"
"@nocobase/resourcer" "0.8.0-alpha.9"
chalk "^4.1.1"
commander "^9.2.0"
find-package-json "^1.2.0"
i18next "^21.6.0"
koa "^2.13.4"
koa-bodyparser "^4.3.0"
koa-static "^5.0.0"
lodash "^4.17.21"
semver "^7.3.7"
xpipe "^1.0.5"
"@nocobase/test@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/test/-/test-0.8.0-alpha.9.tgz#40aaed50af9b8fd23c0666156c806273c75b0a3f"
integrity sha512-bpzcogPKzfq8mjIsLDy0xlsd0dNAUgmju9kk+RPV5wNZfhvofaA7YduexawbL+dLJQC+iyjmhAhARxl8rVhKuA==
dependencies:
"@nocobase/server" "0.8.0-alpha.9"
"@types/supertest" "^2.0.11"
mockjs "^1.1.0"
mysql2 "^2.3.3"
pg "^8.7.3"
pg-hstore "^2.3.4"
sqlite3 "^5.0.8"
supertest "^6.1.6"
"@nocobase/utils@0.8.0-alpha.9":
version "0.8.0-alpha.9"
resolved "https://registry.yarnpkg.com/@nocobase/utils/-/utils-0.8.0-alpha.9.tgz#fa7e203412e91ab7a6ebb12a6d53d83e09465591"
integrity sha512-oEqKs4+0sO4x0TFEtf+Tf1nIkb9q+9y9YmrqOn6MyMo/ejTSh6nlNt1rAYgs02gTP4uHkSOb2/4K4oDm0JXLdg==
dependencies:
"@hapi/topo" "^6.0.0"
deepmerge "^4.2.2"
flat-to-nested "^1.1.1"
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@ -6949,11 +6776,6 @@ async@^2.6.3, async@~2.6.1:
dependencies: dependencies:
lodash "^4.17.14" lodash "^4.17.14"
async@^3.2.3:
version "3.2.4"
resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
asynckit@^0.4.0: asynckit@^0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -8334,7 +8156,7 @@ color-support@^1.1.2, color-support@^1.1.3:
resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
color@^3.0.0, color@^3.1.3: color@^3.0.0:
version "3.2.1" version "3.2.1"
resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
@ -8357,14 +8179,6 @@ colors@~1.2.1:
resolved "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc" resolved "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc"
integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg== integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==
colorspace@1.1.x:
version "1.1.4"
resolved "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243"
integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==
dependencies:
color "^3.1.3"
text-hex "1.0.x"
columnify@^1.5.4: columnify@^1.5.4:
version "1.5.4" version "1.5.4"
resolved "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" resolved "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
@ -9268,11 +9082,6 @@ csstype@^3.0.2:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b" resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b"
integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw== integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==
csstype@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
csstype@^3.0.8: csstype@^3.0.8:
version "3.1.0" version "3.1.0"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
@ -9322,14 +9131,6 @@ d3-timer@^1.0.9:
resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5"
integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==
dagre@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee"
integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
dependencies:
graphlib "^2.1.8"
lodash "^4.17.15"
dargs@^7.0.0: dargs@^7.0.0:
version "7.0.0" version "7.0.0"
resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc"
@ -10049,11 +9850,6 @@ emojis-list@^3.0.0:
resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
enabled@2.0.x:
version "2.0.0"
resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
encodeurl@^1.0.2: encodeurl@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@ -10942,7 +10738,7 @@ fclone@1.0.11, fclone@~1.0.11:
resolved "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" resolved "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640"
integrity sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA= integrity sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=
fecha@^4.2.0, fecha@~4.2.0: fecha@~4.2.0:
version "4.2.3" version "4.2.3"
resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
@ -10973,13 +10769,6 @@ file-saver@^2.0.5:
resolved "https://registry.npmmirror.com/file-saver/download/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38" resolved "https://registry.npmmirror.com/file-saver/download/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA== integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==
file-stream-rotator@^0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz#007019e735b262bb6c6f0197e58e5c87cb96cec3"
integrity sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==
dependencies:
moment "^2.29.1"
file-type@^3.3.0: file-type@^3.3.0:
version "3.9.0" version "3.9.0"
resolved "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" resolved "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
@ -11158,11 +10947,6 @@ fmin@^0.0.2:
tape "^4.5.1" tape "^4.5.1"
uglify-js "^2.6.2" uglify-js "^2.6.2"
fn.name@1.x.x:
version "1.1.0"
resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
follow-redirects@^1.14.0, follow-redirects@^1.14.8: follow-redirects@^1.14.0, follow-redirects@^1.14.8:
version "1.14.9" version "1.14.9"
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
@ -11794,13 +11578,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
graphlib@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da"
integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
dependencies:
lodash "^4.17.15"
growly@^1.3.0: growly@^1.3.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
@ -14197,16 +13974,6 @@ jmespath@0.15.0:
resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217"
integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=
jquery-mousewheel@^3.1.13:
version "3.1.13"
resolved "https://registry.yarnpkg.com/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz#06f0335f16e353a695e7206bf50503cb523a6ee5"
integrity sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg==
jquery@^3.5.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.1.tgz#fab0408f8b45fc19f956205773b62b292c147a16"
integrity sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==
js-base64@^2.5.2: js-base64@^2.5.2:
version "2.6.4" version "2.6.4"
resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
@ -14674,11 +14441,6 @@ koa@^2.13.4:
type-is "^1.6.16" type-is "^1.6.16"
vary "^1.1.2" vary "^1.1.2"
kuler@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
latest-version@^3.0.0: latest-version@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
@ -14919,7 +14681,7 @@ lockfile@^1.0.4:
dependencies: dependencies:
signal-exit "^3.0.2" signal-exit "^3.0.2"
lodash-es@^4.17.11, lodash-es@^4.17.15: lodash-es@^4.17.11:
version "4.17.21" version "4.17.21"
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
@ -15086,17 +14848,6 @@ log-driver@^1.2.7:
resolved "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" resolved "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8"
integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==
logform@^2.3.2, logform@^2.4.0:
version "2.4.2"
resolved "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz#a617983ac0334d0c3b942c34945380062795b47c"
integrity sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==
dependencies:
"@colors/colors" "1.5.0"
fecha "^4.2.0"
ms "^2.1.1"
safe-stable-stringify "^2.3.1"
triple-beam "^1.3.0"
long@^4.0.0: long@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
@ -15989,7 +15740,7 @@ moment-timezone@^0.5.31:
dependencies: dependencies:
moment ">= 2.9.0" moment ">= 2.9.0"
moment@2.x, moment@^2.29.1: moment@2.x:
version "2.29.4" version "2.29.4"
resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
@ -16004,11 +15755,6 @@ moo@^0.5.0:
resolved "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4" resolved "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4"
integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w== integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==
mousetrap@^1.6.5:
version "1.6.5"
resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9"
integrity sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==
mri@^1.1.5: mri@^1.1.5:
version "1.2.0" version "1.2.0"
resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
@ -16689,11 +16435,6 @@ object-copy@^0.1.0:
define-property "^0.2.5" define-property "^0.2.5"
kind-of "^3.0.3" kind-of "^3.0.3"
object-hash@^2.0.1:
version "2.2.0"
resolved "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
object-inspect@^1.11.0, object-inspect@^1.9.0: object-inspect@^1.11.0, object-inspect@^1.9.0:
version "1.11.0" version "1.11.0"
resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1"
@ -16814,13 +16555,6 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0:
dependencies: dependencies:
wrappy "1" wrappy "1"
one-time@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45"
integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
dependencies:
fn.name "1.x.x"
onetime@^2.0.0: onetime@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@ -19763,7 +19497,7 @@ readable-stream@1.1.x:
isarray "0.0.1" isarray "0.0.1"
string_decoder "~0.10.x" string_decoder "~0.10.x"
"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.4.0, readable-stream@^3.6.0: "readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.6.0:
version "3.6.0" version "3.6.0"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@ -20644,11 +20378,6 @@ safe-regex@^1.1.0:
dependencies: dependencies:
ret "~0.1.10" ret "~0.1.10"
safe-stable-stringify@^2.3.1:
version "2.4.1"
resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz#34694bd8a30575b7f94792aa51527551bd733d61"
integrity sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2" version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@ -21337,11 +21066,6 @@ stable@^0.1.8:
resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
stack-utils@^1.0.1: stack-utils@^1.0.1:
version "1.0.5" version "1.0.5"
resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b"
@ -21981,11 +21705,6 @@ text-extensions@^1.0.0:
resolved "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" resolved "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26"
integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==
text-hex@1.0.x:
version "1.0.0"
resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
text-table@^0.2.0: text-table@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@ -22243,11 +21962,6 @@ trim-newlines@^3.0.0:
resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144"
integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
triple-beam@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
trough@^1.0.0: trough@^1.0.0:
version "1.0.5" version "1.0.5"
resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
@ -23072,11 +22786,6 @@ util@^0.11.0:
dependencies: dependencies:
inherits "2.0.3" inherits "2.0.3"
utility-types@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b"
integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
utility@0.1.11: utility@0.1.11:
version "0.1.11" version "0.1.11"
resolved "https://registry.npmjs.org/utility/-/utility-0.1.11.tgz#fde60cf9b4e4751947a0cf5d104ce29367226715" resolved "https://registry.npmjs.org/utility/-/utility-0.1.11.tgz#fde60cf9b4e4751947a0cf5d104ce29367226715"
@ -23469,42 +23178,6 @@ window-size@0.1.0:
resolved "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" resolved "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=
winston-daily-rotate-file@^4.7.1:
version "4.7.1"
resolved "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz#f60a643af87f8867f23170d8cd87dbe3603a625f"
integrity sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==
dependencies:
file-stream-rotator "^0.6.1"
object-hash "^2.0.1"
triple-beam "^1.3.0"
winston-transport "^4.4.0"
winston-transport@^4.4.0, winston-transport@^4.5.0:
version "4.5.0"
resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa"
integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==
dependencies:
logform "^2.3.2"
readable-stream "^3.6.0"
triple-beam "^1.3.0"
winston@^3.8.2:
version "3.8.2"
resolved "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz#56e16b34022eb4cff2638196d9646d7430fdad50"
integrity sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==
dependencies:
"@colors/colors" "1.5.0"
"@dabh/diagnostics" "^2.0.2"
async "^3.2.3"
is-stream "^2.0.0"
logform "^2.4.0"
one-time "^1.0.0"
readable-stream "^3.4.0"
safe-stable-stringify "^2.3.1"
stack-trace "0.0.x"
triple-beam "^1.3.0"
winston-transport "^4.5.0"
wkx@^0.5.0: wkx@^0.5.0:
version "0.5.0" version "0.5.0"
resolved "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" resolved "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c"