Skip to content

Commit

Permalink
feat: loon plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
baranwang committed Oct 20, 2024
1 parent 6563bfa commit cfc560a
Show file tree
Hide file tree
Showing 16 changed files with 196 additions and 150 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
"source.organizeImports.biome": "explicit"
},
"conventionalCommits.scopes": ["arguments-builder", "sgmoudle-tools"],
"cSpell.words": ["iringo", "modkit", "rsbuild"]
"cSpell.words": ["iringo", "MITM", "modkit", "rsbuild"]
}
2 changes: 2 additions & 0 deletions packages/modkit/core/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import minimist from 'minimist';
import { useRsbuild } from './rsbuild';

export async function initCommand() {
logger.greet(` ModKit v${process.env.MODKIT_VERSION}\n`);

// 清空插件管理器中的插件
manager.clear();

Expand Down
1 change: 1 addition & 0 deletions packages/modkit/core/src/exports-plugins/loon.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from '@iringo/modkit-plugin-loon';
export type * from '@iringo/modkit-plugin-loon/types';
2 changes: 1 addition & 1 deletion packages/modkit/plugins/loon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dev": "modern build -w",
"build": "modern build"
},
"files": ["dist", "CHANGELOG.md"],
"files": ["dist", "types", "CHANGELOG.md"],
"dependencies": {
"@iringo/modkit-shared": "workspace:^"
},
Expand Down
21 changes: 20 additions & 1 deletion packages/modkit/plugins/loon/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import type { ModkitPlugin } from '@iringo/modkit-shared';

export type LoonArgumentType = 'input' | 'select' | 'switch' | 'exclude';

export const pluginLoon = (): ModkitPlugin => {
return {
name: 'loon',
setup() {
return {};
return {
configurePlatform() {
return {
extension: '.plugin',
template: process.env.TEMP || '',
};
},
modifySource({ source }) {
source ??= {};
source.arguments = source.arguments?.filter((item) => {
if (typeof item.type === 'object' && item.type.loon === 'exclude') {
return false;
}
return true;
});
return source;
},
};
},
};
};
136 changes: 136 additions & 0 deletions packages/modkit/plugins/loon/src/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { Template, logger } from '@iringo/modkit-shared';
import type { LoonArgumentType } from './index';

export class LoonTemplate extends Template {
get General() {
return this.renderKeyValuePairs(this.content.loonGeneral).trim();
}

get Rule() {
return this.content.rule
?.map((rule) => {
if (typeof rule === 'string') {
return rule;
}
switch (rule.type) {
case 'RULE-SET': {
let result = `RULE-SET, ${this.utils.getFilePath(rule.assetKey)}`;
if (rule.policyName) {
result += `, ${rule.policyName}`;
}
return result;
}
default:
break;
}
})
.join('\n')
.trim();
}

get Argument() {
return this.source.arguments
?.map((arg) => {
let result = arg.key;
let type: LoonArgumentType = 'input';
if (arg.type === 'boolean') {
type = 'switch';
} else if (arg.options && arg.type !== 'array') {
// 只有在有选项且不是数组类型时才使用 select
type = 'select';
}
result += ` = ${type}`;
result += `,${this.#getDefaultValue(arg.defaultValue)}`;
if (arg.options && type === 'select') {
result += ',';
result += arg.options
.filter((item) => item.key !== arg.defaultValue)
.map((option) => `${this.#getDefaultValue(option.key)}`)
.join(',');
}
if (arg.name) {
result += `,tag=${arg.name}`;
}
if (arg.description) {
result += `,desc=${arg.description}`;
}
return result;
})
.join('\n')
.trim();
}

get Script() {
return this.content.script?.map((script, index) => {
let line = '';
switch (script.type) {
case 'http-request':
case 'http-response':
line += `${script.type} ${script.pattern},`;
break;
case 'cron':
line += `${script.type} "${script.cronexp}",`;
break;
case 'generic':
line += `${script.type} `;
break;
// case 'network-changed':
case 'event':
line += 'network-changed ';
break;
case 'dns':
logger.warn('[Loon] Unsupported script type: dns');
break;
}
line += `script-path=${this.utils.getScriptPath(script.scriptKey)},`;
line += this.objectEntries(script)
.map(([key, value]) => {
switch (key) {
case 'name':
return `tag = ${value || `Script${index}`}`;
case 'argument':
return `argument = ${value}`;
case 'injectArgument': {
if (!script.argument && value) {
return `argument = [${this.source.arguments?.map((item) => `{${item.key}}`).join(',')}]`;
}
return '';
}
case 'type':
case 'pattern':
case 'cronexp':
case 'scriptKey':
return '';

default:
return `${key} = ${value}`;
}
})
.filter(Boolean)
.join(',')
.trim();
return line;
});
}

get MITM() {
return this.content.mitm?.hostname?.join(', ');
}

#getDefaultValue(defaultValue: any): any {
switch (typeof defaultValue) {
case 'string':
return `"${defaultValue}"`;
case 'number':
case 'boolean':
return defaultValue;
case 'object':
if (Array.isArray(defaultValue) && defaultValue.length > 0) {
return this.#getDefaultValue(defaultValue[0]);
}
return '""';
default:
return '""';
}
}
}
2 changes: 1 addition & 1 deletion packages/modkit/plugins/loon/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"outDir": "./dist",
"baseUrl": "./"
},
"include": ["src"]
"include": ["src", "types"]
}
12 changes: 12 additions & 0 deletions packages/modkit/plugins/loon/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '@iringo/modkit-shared';
import type { LoonArgumentType } from '../dist/index';

declare module '@iringo/modkit-shared' {
interface PluginModuleContent {
loonGeneral?: Record<string, string>;
}

interface PluginArgumentType {
loon?: LoonArgumentType;
}
}
2 changes: 1 addition & 1 deletion packages/modkit/plugins/surge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const pluginSurge = (): ModkitPlugin => {
onAfterStartDevServer({ rsbuildServer }) {
const moduleRemoteUrl = `http://${appContext.ip}:${rsbuildServer.port}/${moduleName}.sgmodule`;
qrcode.generate(`surge:///install-module?url=${encodeURIComponent(moduleRemoteUrl)}`, { small: true });
api.logger.ready('Scan the QR code to install the module, or manually import:', moduleRemoteUrl);
api.logger.ready('[Surge] Scan the QR code to install the module, or manually import:', moduleRemoteUrl);
},
};
},
Expand Down
2 changes: 1 addition & 1 deletion packages/modkit/plugins/surge/src/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Template } from '@iringo/modkit-shared';

export class SurgeTemplate extends Template {
get General() {
return this.renderKeyValuePairs(this.content.general).trim();
return this.renderKeyValuePairs(this.content.surgeGeneral).trim();
}

get Host() {
Expand Down
14 changes: 5 additions & 9 deletions packages/modkit/plugins/surge/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import '@iringo/modkit-shared';

declare module '@iringo/modkit-shared' {
interface PluginModuleContent {
general?: Record<string, string>;
surgeGeneral?: Record<string, string>;
host?: Record<string, string>;
mitm?: {
hostname?: string[];
clientSourceAddress?: string[];
};
urlRewrite?: string[];
headerRewrite?: string[];
bodyRewrite?: string[];
mapLocal?: string[];
}

interface PluginModuleMITM {
clientSourceAddress?: string[];
}

interface PluginArgumentType {
Expand Down
134 changes: 0 additions & 134 deletions packages/modkit/shared/src/config/types.ts

This file was deleted.

4 changes: 4 additions & 0 deletions packages/modkit/shared/src/plugin/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@ export class Template {
renderLines(lines?: string[]) {
return (lines || []).join('\n');
}

objectEntries<T extends Record<string, any>>(obj: T): [keyof T, T[keyof T]][] {
return Object.entries(obj);
}
}
Loading

0 comments on commit cfc560a

Please sign in to comment.