@nweb/core
Advanced tools
+19
-0
@@ -63,2 +63,21 @@ export declare function Readonly(target: any, property: any, descriptor: any): any; | ||
| } | ||
| type AspectType = 'before' | 'after'; | ||
| type AspectScope = 'component' | 'bean' | 'service' | string; | ||
| export declare class AspectMatcher { | ||
| private readonly type; | ||
| private readonly pattern; | ||
| private readonly scope; | ||
| private readonly aspect; | ||
| private component; | ||
| constructor(type: AspectType, pattern: string | RegExp, scope: AspectScope, aspect: string); | ||
| bind(component: any): void; | ||
| match(component: any, method: string): boolean; | ||
| before(target: any, method: string, args: any[]): Promise<boolean>; | ||
| after(target: any, method: string, args: any[], result: any): Promise<void>; | ||
| } | ||
| export declare function Aspect(point: { | ||
| type: AspectType; | ||
| pattern: string | RegExp; | ||
| scope?: AspectScope; | ||
| } | string): any; | ||
| export declare function Assist(assist: 'search' | 'get' | 'create' | 'modify' | 'delete' | Function): any; | ||
@@ -65,0 +84,0 @@ export declare function Annotation(annotation: Record<string, any>): any; |
+65
-1
@@ -20,3 +20,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Adviser = void 0; | ||
| exports.AspectMatcher = exports.Adviser = void 0; | ||
| exports.Readonly = Readonly; | ||
@@ -33,2 +33,3 @@ exports.Component = Component; | ||
| exports.Advice = Advice; | ||
| exports.Aspect = Aspect; | ||
| exports.Assist = Assist; | ||
@@ -216,2 +217,65 @@ exports.Annotation = Annotation; | ||
| Advice.type = 'advice'; | ||
| class AspectMatcher { | ||
| type; | ||
| pattern; | ||
| scope; | ||
| aspect; | ||
| component; | ||
| constructor(type, pattern, scope, aspect) { | ||
| this.type = type; | ||
| this.pattern = typeof pattern === 'string' ? new RegExp(pattern.replace(/\*/g, '.*')) : pattern; | ||
| this.scope = scope; | ||
| this.aspect = aspect; | ||
| } | ||
| bind(component) { | ||
| this.component = component; | ||
| } | ||
| match(component, method) { | ||
| if (this.scope !== 'any') { | ||
| const type = component.annotation.type; | ||
| if (this.scope !== type) { | ||
| return new RegExp(this.scope).test(component.annotation.name); | ||
| } | ||
| } | ||
| return this.pattern.test(method); | ||
| } | ||
| async before(target, method, args) { | ||
| if (this.type === 'before') { | ||
| const rs = await this.component[this.aspect]?.call(target, method, args); | ||
| return rs !== false; | ||
| } | ||
| } | ||
| async after(target, method, args, result) { | ||
| if (this.type === 'after') { | ||
| return this.component[this.aspect]?.call(target, method, args, result); | ||
| } | ||
| } | ||
| } | ||
| exports.AspectMatcher = AspectMatcher; | ||
| function Aspect(point) { | ||
| return (target, property) => { | ||
| let type, pattern, scope; | ||
| if (typeof point === 'string') { | ||
| const [mType, mScope, mPattern] = point.match(/^@(before|after)\s+([a-zA-Z0-9_]+)#(.*)$/); | ||
| if (!mType || !mScope || !mPattern) { | ||
| throw new Error('Aspect point format error eg: @before componentName#test*'); | ||
| } | ||
| type = mType; | ||
| scope = mScope; | ||
| pattern = mPattern; | ||
| } | ||
| else { | ||
| type = point.type; | ||
| pattern = point.pattern; | ||
| scope = point.scope; | ||
| } | ||
| scope = scope || 'component'; | ||
| let annotation = { | ||
| aspect: { | ||
| [property]: new AspectMatcher(type, pattern, scope, property) | ||
| } | ||
| }; | ||
| (0, util_2.setAnnotation)(target, annotation); | ||
| }; | ||
| } | ||
| function Assist(assist) { | ||
@@ -218,0 +282,0 @@ const set = (target, property) => { |
+23
-18
@@ -115,22 +115,27 @@ "use strict"; | ||
| const startup = async (options) => { | ||
| let begin = Date.now(); | ||
| printLogo(); | ||
| let opts = {}; | ||
| if (typeof options === 'function') { | ||
| opts.callback = options; | ||
| try { | ||
| let begin = Date.now(); | ||
| printLogo(); | ||
| let opts = {}; | ||
| if (typeof options === 'function') { | ||
| opts.callback = options; | ||
| } | ||
| else if (typeof options === 'string') { | ||
| opts.active = options; | ||
| } | ||
| else { | ||
| opts = { ...options }; | ||
| } | ||
| let { callback = (context) => void 0, active = process.env.active || 'development', conf = process.env.conf || (path.resolve('.') + path.sep + 'config') } = opts; | ||
| applicationContext = new VWebApp_1.default(conf, active); | ||
| await applicationContext.initialize(); | ||
| (global.__vweb_modules || []).forEach(({ module, config }) => { | ||
| applicationContext.mount(module, config); | ||
| }); | ||
| await callback(applicationContext); | ||
| await applicationContext.launch(); | ||
| } | ||
| else if (typeof options === 'string') { | ||
| opts.active = options; | ||
| catch (e) { | ||
| applicationContext.logger.error('应用启动失败', e); | ||
| } | ||
| else { | ||
| opts = { ...options }; | ||
| } | ||
| let { callback = (context) => void 0, active = process.env.active || 'development', conf = process.env.conf || (path.resolve('.') + path.sep + 'config') } = opts; | ||
| applicationContext = new VWebApp_1.default(conf, active); | ||
| await applicationContext.initialize(); | ||
| (global.__vweb_modules || []).forEach(({ module, config }) => { | ||
| applicationContext.mount(module, config); | ||
| }); | ||
| await callback(applicationContext); | ||
| await applicationContext.launch(); | ||
| }; | ||
@@ -137,0 +142,0 @@ exports.startup = startup; |
+2
-0
@@ -5,2 +5,3 @@ import Configuration from './conf'; | ||
| import { NacosConfig } from "./conf/nacos"; | ||
| import { AspectMatcher } from "./anno"; | ||
| export declare class StartupListener { | ||
@@ -34,2 +35,3 @@ startup(context: VWebApplicationContext): Promise<void>; | ||
| readonly config: Configuration; | ||
| readonly aspects: Array<AspectMatcher>; | ||
| constructor(conf: string | Environment, active?: string); | ||
@@ -36,0 +38,0 @@ initialize(): Promise<void>; |
+57
-24
@@ -255,31 +255,56 @@ "use strict"; | ||
| }; | ||
| try { | ||
| let wrapper = (global.__vweb_wrappers || {})[type]; | ||
| if (!wrapper) { | ||
| wrapper = require(`@nweb/${type}-wrapper`); | ||
| descriptor = function (context, component) { | ||
| let getFun = void 0; | ||
| try { | ||
| let wrapper = (global.__vweb_wrappers || {})[type]; | ||
| if (!wrapper) { | ||
| wrapper = require(`@nweb/${type}-wrapper`); | ||
| } | ||
| getFun = (wrapper.default || wrapper)?.(context, component)?.get; | ||
| logger.info(`Load @nweb/${type}-wrapper success`); | ||
| } | ||
| descriptor = wrapper.default || wrapper; | ||
| logger.info(`Load @nweb/${type}-wrapper success`); | ||
| } | ||
| catch (e) { | ||
| if (e.code !== 'MODULE_NOT_FOUND') { | ||
| logger.error(e); | ||
| catch (e) { | ||
| if (e.code !== 'MODULE_NOT_FOUND') { | ||
| logger.error(e); | ||
| } | ||
| } | ||
| descriptor = function (context, component) { | ||
| return { | ||
| get(target, p) { | ||
| if (target[p] !== undefined) { | ||
| return target[p]; | ||
| return { | ||
| get(target, p) { | ||
| let value = getFun?.(target, p) || target[p]; | ||
| if (value !== undefined) { | ||
| if (typeof value === 'function') { | ||
| return new Proxy(value, { | ||
| async apply(method, thisArg, args) { | ||
| const aspects = self.aspects.filter(aspect => aspect.match(target, p)); | ||
| const beforeList = await Promise.all(aspects.map(aspect => aspect.before(target, p, args))); | ||
| if (beforeList.includes(false)) { | ||
| return; | ||
| } | ||
| else if (logger.isDebugEnabled()) { | ||
| logger.debug(`Component ${thisArg.annotation.name}#${p}(${(args || []).map((e, i) => `arg${i}`).join(', ')}) aspect before trigger`); | ||
| } | ||
| const result = await method.apply(thisArg, args); | ||
| if (logger.isDebugEnabled()) { | ||
| logger.debug(`Component ${thisArg.annotation.name}#${p}(${(args || []).map((e, i) => `arg${i}`).join(', ')}) return ${result || 'void'}`); | ||
| } | ||
| let afterList = await Promise.all(aspects.map(aspect => aspect.after(target, p, args, result))); | ||
| if (afterList.length && logger.isDebugEnabled()) { | ||
| logger.debug(`Component ${thisArg.annotation.name}#${p}(${(args || []).map((e, i) => `arg${i}`).join(', ')}) aspect after trigger`); | ||
| } | ||
| return result; | ||
| } | ||
| }); | ||
| } | ||
| if (p === 'logger') { | ||
| return context.log4j.getLogger(component.constructor?.name || component.annotation?.name || 'default'); | ||
| } | ||
| if (p in expansion) { | ||
| return expansion[p]; | ||
| } | ||
| return context.getComponentByName(p); | ||
| return value; | ||
| } | ||
| }; | ||
| if (p === 'logger') { | ||
| return context.log4j.getLogger(component.constructor?.name || component.annotation?.name || 'default'); | ||
| } | ||
| if (p in expansion) { | ||
| return expansion[p]; | ||
| } | ||
| return context.getComponentByName(p); | ||
| } | ||
| }; | ||
| } | ||
| }; | ||
| cache.set(type, descriptor); | ||
@@ -304,2 +329,3 @@ } | ||
| config; | ||
| aspects = []; | ||
| constructor(conf, active) { | ||
@@ -489,2 +515,9 @@ this.components = { | ||
| continue; | ||
| if (annotation.aspect) { | ||
| for (let prop of Object.keys(annotation.aspect)) { | ||
| const aspectMatcher = annotation.aspect[prop]; | ||
| aspectMatcher.bind(component); | ||
| this.aspects.push(aspectMatcher); | ||
| } | ||
| } | ||
| this.register(annotation, component); | ||
@@ -491,0 +524,0 @@ components.push(component); |
+1
-1
| { | ||
| "name": "@nweb/core", | ||
| "version": "1.1.8", | ||
| "version": "1.1.9", | ||
| "description": "web核心组件", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
145962
3.77%4234
2.99%