summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/api')
-rw-r--r--src/api/rule-provider.ts74
-rw-r--r--src/api/rules.js8
-rw-r--r--src/api/rules.ts41
3 files changed, 115 insertions, 8 deletions
diff --git a/src/api/rule-provider.ts b/src/api/rule-provider.ts
new file mode 100644
index 0000000..5d39527
--- /dev/null
+++ b/src/api/rule-provider.ts
@@ -0,0 +1,74 @@
+import { getURLAndInit } from 'src/misc/request-helper';
+import { ClashAPIConfig } from 'src/types';
+
+export type RuleProvider = RuleProviderAPIItem & { idx: number };
+
+export type RuleProviderAPIItem = {
+ behavior: string;
+ name: string;
+ ruleCount: number;
+ type: 'Rule';
+ // example value "2020-06-30T16:23:01.44143802+08:00"
+ updatedAt: string;
+ vehicleType: 'HTTP' | 'File';
+};
+
+type RuleProviderAPIData = {
+ providers: Record<string, RuleProviderAPIItem>;
+};
+
+function normalizeAPIResponse(data: RuleProviderAPIData) {
+ const providers = data.providers;
+ const names = Object.keys(providers);
+ const byName: Record<string, RuleProvider> = {};
+
+ // attach an idx to each item
+ for (let i = 0; i < names.length; i++) {
+ const name = names[i];
+ byName[name] = { ...providers[name], idx: i };
+ }
+
+ return { byName, names };
+}
+
+export async function fetchRuleProviders(
+ endpoint: string,
+ apiConfig: ClashAPIConfig
+) {
+ const { url, init } = getURLAndInit(apiConfig);
+
+ let data = { providers: {} };
+ try {
+ const res = await fetch(url + endpoint, init);
+ if (res.ok) {
+ data = await res.json();
+ }
+ } catch (err) {
+ // log and ignore
+ // eslint-disable-next-line no-console
+ console.log('failed to GET /providers/rules', err);
+ }
+ return normalizeAPIResponse(data);
+}
+
+export async function refreshRuleProviderByName({
+ name,
+ apiConfig,
+}: {
+ name: string;
+ apiConfig: ClashAPIConfig;
+}) {
+ const { url, init } = getURLAndInit(apiConfig);
+ try {
+ const res = await fetch(url + `/providers/rules/${name}`, {
+ method: 'PUT',
+ ...init,
+ });
+ return res.ok;
+ } catch (err) {
+ // log and ignore
+ // eslint-disable-next-line no-console
+ console.log('failed to PUT /providers/rules/:name', err);
+ return false;
+ }
+}
diff --git a/src/api/rules.js b/src/api/rules.js
deleted file mode 100644
index 574de96..0000000
--- a/src/api/rules.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { getURLAndInit } from '../misc/request-helper';
-
-const endpoint = '/rules';
-
-export async function fetchRules(apiConfig) {
- const { url, init } = getURLAndInit(apiConfig);
- return await fetch(url + endpoint, init);
-}
diff --git a/src/api/rules.ts b/src/api/rules.ts
new file mode 100644
index 0000000..b57b0e3
--- /dev/null
+++ b/src/api/rules.ts
@@ -0,0 +1,41 @@
+import invariant from 'invariant';
+import { getURLAndInit } from 'src/misc/request-helper';
+import { ClashAPIConfig } from 'src/types';
+
+// const endpoint = '/rules';
+
+type RuleItem = RuleAPIItem & { id: number };
+
+type RuleAPIItem = {
+ type: string;
+ payload: string;
+ proxy: string;
+};
+
+function normalizeAPIResponse(json: {
+ rules: Array<RuleAPIItem>;
+}): Array<RuleItem> {
+ invariant(
+ json.rules && json.rules.length >= 0,
+ 'there is no valid rules list in the rules API response'
+ );
+
+ // attach an id
+ return json.rules.map((r: RuleAPIItem, i: number) => ({ ...r, id: i }));
+}
+
+export async function fetchRules(endpoint: string, apiConfig: ClashAPIConfig) {
+ let json = { rules: [] };
+ try {
+ const { url, init } = getURLAndInit(apiConfig);
+ const res = await fetch(url + endpoint, init);
+ if (res.ok) {
+ json = await res.json();
+ }
+ } catch (err) {
+ // log and ignore
+ // eslint-disable-next-line no-console
+ console.log('failed to fetch rules', err);
+ }
+ return normalizeAPIResponse(json);
+}