From 5aef458aad02bc26a35cac9f1b9228df1e57b218 Mon Sep 17 00:00:00 2001 From: Shigma Date: Mon, 26 Feb 2024 16:47:07 +0800 Subject: [PATCH] feat(core): support intercept config --- packages/core/package.json | 2 +- packages/core/src/index.ts | 59 +++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 439c834..016da13 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "yakumo", "description": "Manage complex workspaces with ease", - "version": "1.0.0-beta.6", + "version": "1.0.0-beta.9", "type": "module", "main": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 811ce39..975da30 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -26,12 +26,6 @@ export const meta: PackageJson = JSON.parse(content) export interface PackageConfig {} -export interface ProjectConfig { - alias?: Dict - commands?: Dict - pipeline?: Dict -} - export interface Manager { name: string version: string @@ -67,8 +61,13 @@ export namespace PackageJson { export interface Events extends cordis.Events {} +export interface Intercept extends cordis.Intercept { + yakumo: Yakumo.Intercept +} + export interface Context { [Context.events]: Events + [Context.intercept]: Intercept yakumo: Yakumo register(name: string, callback: () => void, options?: Options): void } @@ -85,6 +84,18 @@ export interface LocateOptions { filter?(meta: PackageJson, path: string): boolean } +export namespace Yakumo { + export interface Intercept { + alias?: Dict + exclude?: string[] + } + + export interface Config extends Intercept { + commands?: Dict + pipeline?: Dict + } +} + export default class Yakumo { cwd: string args = process.argv.slice(2) @@ -94,7 +105,7 @@ export default class Yakumo { indent = detect(content).indent commands: Dict = {} - constructor(ctx: Context, public config: ProjectConfig) { + constructor(ctx: Context, public config: Yakumo.Config) { ctx.provide('yakumo', undefined, true) ctx.mixin('yakumo', ['register']) ctx.yakumo = this @@ -144,8 +155,36 @@ export default class Yakumo { }))).filter(Boolean)) } + resolveIntercept(): Yakumo.Intercept { + const caller: Context = this[Context.current] + let result = this.config + let intercept = caller[Context.intercept] + while (intercept) { + result = { + ...result, + ...intercept.yakumo, + alias: { + ...result.alias, + ...intercept.yakumo?.alias, + }, + exclude: [ + ...result.exclude || [], + ...intercept.yakumo?.exclude || [], + ], + } + intercept = Object.getPrototypeOf(intercept) + } + return result + } + locate(name: string | string[], options: LocateOptions = {}): string[] { - const filter = options.filter || ((meta) => options.includeRoot || !meta.workspaces) + const { alias, exclude } = this.resolveIntercept() + const defaultFilter = options.filter || ((meta) => options.includeRoot || !meta.workspaces) + const filter = (meta: PackageJson, path: string) => { + return defaultFilter(meta, path) && !exclude?.some((pattern) => { + return new RegExp('^/' + pattern.replace(/\*/g, '[^/]+') + '$').test(path) + }) + } if (Array.isArray(name)) { if (!name.length) { return Object.keys(this.workspaces).filter((folder) => { @@ -156,8 +195,8 @@ export default class Yakumo { } } - if (this.config.alias?.[name]) { - return makeArray(this.config.alias[name]).map((path) => { + if (alias?.[name]) { + return makeArray(alias[name]).map((path) => { if (!this.workspaces[path]) { throw new Error(`cannot find workspace ${path} resolved by ${name}`) }