@artus/core
Advanced tools
Comparing version 2.0.5 to 2.1.0-alpha.0
import { PluginType } from './types'; | ||
export declare function topologicalSort(pluginInstanceMap: Map<string, PluginType>, pluginDepEdgeList: [string, string][]): string[]; | ||
import { LoggerType } from '../logger'; | ||
export declare function sortPlugins(pluginInstanceMap: Map<string, PluginType>, logger: LoggerType): PluginType[]; | ||
export declare function getPackagePath(packageName: string, paths?: string[]): string; | ||
export declare function getInlinePackageEntryPath(packagePath: string): Promise<string>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getInlinePackageEntryPath = exports.getPackagePath = exports.topologicalSort = void 0; | ||
exports.getInlinePackageEntryPath = exports.getPackagePath = exports.sortPlugins = void 0; | ||
const tslib_1 = require("tslib"); | ||
const path_1 = tslib_1.__importDefault(require("path")); | ||
const compatible_require_1 = tslib_1.__importDefault(require("../utils/compatible_require")); | ||
// A utils function that toplogical sort plugins | ||
function topologicalSort(pluginInstanceMap, pluginDepEdgeList) { | ||
function sortPlugins(pluginInstanceMap, logger) { | ||
var _a; | ||
const res = []; | ||
const indegree = new Map(); | ||
pluginDepEdgeList.forEach(([to]) => { | ||
var _a; | ||
indegree.set(to, ((_a = indegree.get(to)) !== null && _a !== void 0 ? _a : 0) + 1); | ||
}); | ||
const queue = []; | ||
for (const [name] of pluginInstanceMap) { | ||
if (!indegree.has(name)) { | ||
queue.push(name); | ||
const sortedPlugins = []; | ||
const visited = {}; | ||
while (sortedPlugins.length < pluginInstanceMap.size) { | ||
let added = false; | ||
for (const [pluginName, plugin] of pluginInstanceMap) { | ||
if (visited[pluginName]) { | ||
continue; | ||
} | ||
let depsSatisfied = true; | ||
for (const dep of (_a = plugin.metadata.dependencies) !== null && _a !== void 0 ? _a : []) { | ||
const depPlugin = pluginInstanceMap.get(dep.name); | ||
if (!depPlugin || !depPlugin.enable) { | ||
if (dep.optional) { | ||
logger === null || logger === void 0 ? void 0 : logger.warn(`Plugin ${plugin.name} need have optional dependency: ${dep.name}.`); | ||
} | ||
else { | ||
throw new Error(`Plugin ${plugin.name} need have dependency: ${dep.name}.`); | ||
} | ||
} | ||
else if (!visited[dep.name]) { // Plugin exist and enabled, need check visited | ||
depsSatisfied = false; | ||
} | ||
} | ||
if (depsSatisfied) { | ||
sortedPlugins.push(plugin); | ||
visited[plugin.name] = true; | ||
added = true; | ||
} | ||
} | ||
} | ||
while (queue.length) { | ||
const cur = queue.shift(); | ||
res.push(cur); | ||
for (const [to, from] of pluginDepEdgeList) { | ||
if (from === cur) { | ||
indegree.set(to, ((_a = indegree.get(to)) !== null && _a !== void 0 ? _a : 0) - 1); | ||
if (indegree.get(to) === 0) { | ||
queue.push(to); | ||
if (!added) { | ||
const cyclePluginNames = []; | ||
const sortedPluginSet = new Set(sortedPlugins.map(p => p.name)); | ||
for (const pluginName of pluginInstanceMap.keys()) { | ||
if (!sortedPluginSet.has(pluginName)) { | ||
cyclePluginNames.push(pluginName); | ||
} | ||
} | ||
throw new Error(`Circular dependency found in plugins: ${cyclePluginNames.join(', ')}`); | ||
} | ||
} | ||
return res; | ||
return sortedPlugins; | ||
} | ||
exports.topologicalSort = topologicalSort; | ||
exports.sortPlugins = sortPlugins; | ||
// A util function of get package path for plugin | ||
@@ -38,0 +53,0 @@ function getPackagePath(packageName, paths = []) { |
import { PluginConfigItem, PluginCreateOptions, PluginType } from './types'; | ||
export declare class PluginFactory { | ||
static create(name: string, item: PluginConfigItem, opts?: PluginCreateOptions): Promise<PluginType>; | ||
static createFromConfig(config: Record<string, PluginConfigItem>, opts?: PluginCreateOptions): Promise<PluginType[]>; | ||
} |
@@ -7,29 +7,14 @@ "use strict"; | ||
class PluginFactory { | ||
static async create(name, item, opts) { | ||
const pluginInstance = new impl_1.Plugin(name, item, opts); | ||
await pluginInstance.init(); | ||
return pluginInstance; | ||
} | ||
static async createFromConfig(config, opts) { | ||
const pluginInstanceMap = new Map(); | ||
for (const [name, item] of Object.entries(config)) { | ||
const pluginInstance = await PluginFactory.create(name, item, opts); | ||
if (pluginInstance.enable) { | ||
if (item.enable) { | ||
const pluginInstance = new impl_1.Plugin(name, item); | ||
await pluginInstance.init(); | ||
pluginInstanceMap.set(name, pluginInstance); | ||
} | ||
} | ||
let pluginDepEdgeList = []; | ||
// Topological sort plugins | ||
for (const [_name, pluginInstance] of pluginInstanceMap) { | ||
pluginInstance.checkDepExisted(pluginInstanceMap); | ||
pluginDepEdgeList = pluginDepEdgeList.concat(pluginInstance.getDepEdgeList()); | ||
} | ||
const pluginSortResult = (0, common_1.topologicalSort)(pluginInstanceMap, pluginDepEdgeList); | ||
if (pluginSortResult.length !== pluginInstanceMap.size) { | ||
const diffPlugin = [...pluginInstanceMap.keys()].filter(name => !pluginSortResult.includes(name)); | ||
throw new Error(`There is a cycle in the dependencies, wrong plugin is ${diffPlugin.join(',')}.`); | ||
} | ||
return pluginSortResult.map(name => pluginInstanceMap.get(name)); | ||
return (0, common_1.sortPlugins)(pluginInstanceMap, opts === null || opts === void 0 ? void 0 : opts.logger); | ||
} | ||
} | ||
exports.PluginFactory = PluginFactory; |
@@ -1,2 +0,2 @@ | ||
import { PluginConfigItem, PluginCreateOptions, PluginMap, PluginMetadata, PluginType } from './types'; | ||
import { PluginConfigItem, PluginMetadata, PluginType } from './types'; | ||
export declare class Plugin implements PluginType { | ||
@@ -8,8 +8,5 @@ name: string; | ||
metaFilePath: string; | ||
private logger?; | ||
constructor(name: string, configItem: PluginConfigItem, opts?: PluginCreateOptions); | ||
constructor(name: string, configItem: PluginConfigItem); | ||
init(): Promise<void>; | ||
checkDepExisted(pluginMap: PluginMap): void; | ||
getDepEdgeList(): [string, string][]; | ||
private checkAndLoadMetadata; | ||
} |
@@ -11,3 +11,3 @@ "use strict"; | ||
class Plugin { | ||
constructor(name, configItem, opts) { | ||
constructor(name, configItem) { | ||
var _a, _b; | ||
@@ -34,3 +34,2 @@ this.importPath = ''; | ||
} | ||
this.logger = opts === null || opts === void 0 ? void 0 : opts.logger; | ||
} | ||
@@ -49,28 +48,2 @@ async init() { | ||
} | ||
checkDepExisted(pluginMap) { | ||
var _a; | ||
if (!this.metadata.dependencies) { | ||
return; | ||
} | ||
for (let i = 0; i < this.metadata.dependencies.length; i++) { | ||
const { name: pluginName, optional } = this.metadata.dependencies[i]; | ||
const instance = pluginMap.get(pluginName); | ||
if (!instance || !instance.enable) { | ||
if (optional) { | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn(`Plugin ${this.name} need have optional dependency: ${pluginName}.`); | ||
} | ||
else { | ||
throw new Error(`Plugin ${this.name} need have dependency: ${pluginName}.`); | ||
} | ||
} | ||
else { | ||
// Plugin exist and enabled, need calc edge | ||
this.metadata.dependencies[i]._enabled = true; | ||
} | ||
} | ||
} | ||
getDepEdgeList() { | ||
var _a, _b, _c; | ||
return (_c = (_b = (_a = this.metadata.dependencies) === null || _a === void 0 ? void 0 : _a.filter(({ optional, _enabled }) => !optional || _enabled)) === null || _b === void 0 ? void 0 : _b.map(({ name: depPluginName }) => [this.name, depPluginName])) !== null && _c !== void 0 ? _c : []; | ||
} | ||
async checkAndLoadMetadata() { | ||
@@ -77,0 +50,0 @@ // check metadata from configItem |
@@ -33,4 +33,2 @@ import { LoggerType } from '../logger'; | ||
init(): Promise<void>; | ||
checkDepExisted(map: PluginMap): void; | ||
getDepEdgeList(): [string, string][]; | ||
} |
{ | ||
"name": "@artus/core", | ||
"version": "2.0.5", | ||
"version": "2.1.0-alpha.0", | ||
"description": "Core package of Artus", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
119796
117
2892
1
11