tachybase_todo/packages/core/resourcer/src/assign.ts
ChengLei Shao 24ea83f0ff
Feat/create nocobase app (#273)
* create-nocobase-app template from [develop]

* change create-nocobase-app package.json config

* feat: load configuration from directory

* feat: configuration repository toObject

* feat: create application from configuration dir

* feat: application factory with plugins options

* export type

* feat: read application config &  application with plugins options

* feat: release command

* fix: database release

* chore: workflow package.json

* feat: nocobase cli package

* feat: console command

* chore: load application in command

* fix: load packages from process.cwd

* feat: cli load env file

* feat: create-nocobase-app

* fix: gitignore create-nocobase-app lib

* fix: sqlite path

* feat: create plugin

* chore: plugin files template

* chore: move cli into application

* chore: create-nocobase-app

* fix: create plugin

* chore: app-client && app-server

* chore: package.json

* feat: create-nocobase-app download template from npm

* chore: create-nocobase-app template

* fix: config of plugin-users

* fix: yarn.lock

* fix: database build error

* fix: yarn.lock

* fix: resourcer config

* chore: cross-env

* chore: app-client dependents

* fix: env

* chore: v0.6.0-alpha.1

* chore: verdaccio

* chore(versions): 😊 publish v0.6.0

* chore(versions): 😊 publish v0.6.1-alpha.0

* chore(versions): 😊 publish v0.6.2-alpha.0

* chore(versions): 😊 publish v0.6.2-alpha.1

* chore: 0.6.2-alpha.2

* feat: workspaces

* chore(versions): 😊 publish v0.6.2-alpha.3

* chore(versions): 😊 publish v0.6.2-alpha.4

* chore: create-nocobase-app

* chore: create-nocobase-app lib

* fix: update tsconfig.jest.json

* chore: .env

* chore(versions): 😊 publish v0.6.2-alpha.5

* chore(versions): 😊 publish v0.6.2-alpha.6

* feat: improve code

* chore(versions): 😊 publish v0.6.2-alpha.7

* fix: cleanup

* chore(versions): 😊 publish v0.6.2-alpha.8

* chore: tsconfig for app server package

* fix: move files

* fix: move files

Co-authored-by: chenos <chenlinxh@gmail.com>
2022-04-17 10:00:42 +08:00

119 lines
2.7 KiB
TypeScript

import lodash from 'lodash';
import deepmerge from 'deepmerge';
type MergeStrategyType = 'merge' | 'deepMerge' | 'overwrite' | 'andMerge' | 'orMerge' | 'intersect' | 'union';
type MergeStrategyFunc = (x: any, y: any) => any;
export type MergeStrategy = MergeStrategyType | MergeStrategyFunc;
export interface MergeStrategies {
[key: string]: MergeStrategy;
}
export default function isPlainObject(value) {
if (Object.prototype.toString.call(value) !== '[object Object]') {
return false;
}
const prototype = Object.getPrototypeOf(value);
return prototype === null || prototype === Object.prototype;
}
function getEnumerableOwnPropertySymbols(target: any): any[] {
return Object.getOwnPropertySymbols
? Object.getOwnPropertySymbols(target).filter((symbol) => target.propertyIsEnumerable(symbol))
: [];
}
function getKeys(target: any) {
return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target));
}
export const mergeStrategies = new Map<MergeStrategyType, MergeStrategyFunc>();
mergeStrategies.set('overwrite', (_, y) => {
return y;
});
mergeStrategies.set('andMerge', (x, y) => {
if (!x && !y) {
return;
}
if (!x) {
return y;
}
if (!y) {
return x;
}
return {
$and: [x, y],
};
});
mergeStrategies.set('orMerge', (x, y) => {
if (!x && !y) {
return;
}
if (!x) {
return y;
}
if (!y) {
return x;
}
return {
$or: [x, y],
};
});
mergeStrategies.set('deepMerge', (x, y) => {
return isPlainObject(x) && isPlainObject(y)
? deepmerge(x, y, {
arrayMerge: (x, y) => y,
})
: y;
});
mergeStrategies.set('merge', (x, y) => {
return isPlainObject(x) && isPlainObject(y) ? Object.assign(x, y) : y;
});
mergeStrategies.set('union', (x, y) => {
if (typeof x === 'string') {
x = x.split(',');
}
if (typeof y === 'string') {
y = y.split(',');
}
return lodash.uniq((x || []).concat(y || []));
});
mergeStrategies.set('intersect', (x, y) => {
if (typeof x === 'string') {
x = x.split(',');
}
if (typeof y === 'string') {
y = y.split(',');
}
if (!Array.isArray(x) || x.length === 0) {
return y || [];
}
if (!Array.isArray(y) || y.length === 0) {
return x || [];
}
return x.filter((v) => y.includes(v));
});
export function assign(target: any, source: any, strategies: MergeStrategies = {}) {
getKeys(source).forEach((sourceKey) => {
const strategy = strategies[sourceKey];
let func = mergeStrategies.get('deepMerge');
if (typeof strategy === 'function') {
func = strategy;
} else if (typeof strategy === 'string' && mergeStrategies.has(strategy as any)) {
func = mergeStrategies.get(strategy as any);
}
target[sourceKey] = func(target[sourceKey], source[sourceKey]);
});
return target;
}