Skip to content

Commit

Permalink
feat: quantumultx plugin
Browse files Browse the repository at this point in the history
Update template.ts
  • Loading branch information
VirgilClyne committed Oct 21, 2024
1 parent 19f79e3 commit f818d3c
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
registry=https://registry.npmjs.org/
link-workspace-packages=true
link-workspace-packages=true
enable-pre-post-scripts=true
13 changes: 13 additions & 0 deletions packages/modkit/plugins/quantumultx/modern.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import fs from 'node:fs';
import { dualBuildConfigs } from '@iringo/modkit-config/modern.config.ts';
import { defineConfig, moduleTools } from '@modern-js/module-tools';

export default defineConfig({
plugins: [moduleTools()],
buildConfig: dualBuildConfigs.map((item) => ({
...item,
define: {
'process.env.TEMP': fs.readFileSync('./template.ejs', 'utf-8'),
},
})),
});
27 changes: 27 additions & 0 deletions packages/modkit/plugins/quantumultx/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@iringo/modkit-plugin-quantumultx",
"version": "0.0.1",
"description": "",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"scripts": {
"dev": "modern build -w",
"build": "modern build"
},
"files": ["dist", "types", "CHANGELOG.md"],
"dependencies": {
"@iringo/modkit-shared": "workspace:^"
},
"devDependencies": {
"@iringo/modkit-config": "workspace:^",
"@modern-js/module-tools": "^2.60.2",
"@types/node": "^20.0.0",
"typescript": "^5.6.2"
},
"repository": {
"type": "git",
"url": "https://github.com/NSRingo/engineering-solutions",
"directory": "packages/modkit/apps/quantumultx"
}
}
45 changes: 45 additions & 0 deletions packages/modkit/plugins/quantumultx/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { ModkitPlugin } from '@iringo/modkit-shared';
import { QuantumultxTemplate } from './template';

export interface QuantumultxPluginOptions {
objectValuesHandler?: (obj: Record<string, any>) => string;
}

export const pluginQuantumultx = ({
objectValuesHandler = (obj) => {
if (Array.isArray(obj)) {
return `"${obj.join()}"`;
}
return `"${JSON.stringify(obj)}"`;
},
}: QuantumultxPluginOptions = {}): ModkitPlugin => {
return {
name: 'quantumultx',
setup() {
return {
configurePlatform() {
return {
extension: '.snippet',
template: process.env.TEMP || '',
};
},
modifySource({ source }) {
source ??= {};
source.arguments = source.arguments?.filter((item) => {
if (typeof item.type === 'object' && item.type.quantumultx === 'exclude') {
return false;
}
return true;
});
return source;
},
templateParameters(params) {
const quantumultxTemplate = new QuantumultxTemplate(params, objectValuesHandler);
return {
quantumultxTemplate,
};
},
};
},
};
};
110 changes: 110 additions & 0 deletions packages/modkit/plugins/quantumultx/src/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Template, logger, objectEntries, toKebabCase } from '@iringo/modkit-shared';

export class QuantumultxTemplate extends Template {
get Metadata() {
const result: Record<string, string | undefined> = {};
result.name = this.metadata.name;
result.desc = this.metadata.description;
result.system = this.metadata.system?.join();
result.version = this.metadata.version;
Object.entries(this.metadata.extra || {}).forEach(([key, value]) => {
result[key] = Array.isArray(value) ? value.join(',') : value;
});
return this.renderKeyValuePairs(result, { prefix: '#!' });
}

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 Rewrite() {
const rewrites: string[] = [];
this.content.rewrite?.forEach((rewrite) => {
switch (rewrite.mode) {
case 'header':
case 'header-add':
case 'header-del':
rewrite.mode = 'request-header';
break;
case undefined:
switch (rewrite.type) {
case 'http-request':
rewrite.mode = 'request-body';
break;
case 'http-response':
rewrite.mode = 'response-body';
break;
}
break;
}
const options = [];
options.push(rewrite.pattern);
options.push('url');
options.push(rewrite.mode);
options.push(rewrite.content || '');
rewrites.push(options.join(' '));
});
return rewrites.join('\n').trim();
}

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

get MITM() {
return this.content.mitm?.hostname?.join(', ');
}
}
26 changes: 26 additions & 0 deletions packages/modkit/plugins/quantumultx/template.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<%= quantumultxTemplate.Metadata %>

<% if (quantumultxTemplate.Host) { %>
#[dns]
<%= quantumultxTemplate.Host %>
<% } %>

<% if (quantumultxTemplate.Rule) { %>
#[filter_local]
<%= quantumultxTemplate.Rule %>
<% } %>

<% if (quantumultxTemplate.Rewrite) { %>
#[rewrite_local]
<%= quantumultxTemplate.Rewrite %>
<% } %>

<% if (quantumultxTemplate.Script) { %>
#[rewrite_local]
<%= quantumultxTemplate.Script %>
<% } %>

<% if (quantumultxTemplate.MITM) { %>
#[mitm]
<%= quantumultxTemplate.MITM %>
<% } %>
8 changes: 8 additions & 0 deletions packages/modkit/plugins/quantumultx/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "@iringo/modkit-config/tsconfig",
"compilerOptions": {
"outDir": "./dist",
"baseUrl": "./"
},
"include": ["src", "types"]
}
19 changes: 19 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f818d3c

Please sign in to comment.