feat: use selector syntax check

This commit is contained in:
lisonge 2023-07-09 23:24:35 +08:00
parent 0f2206bbe4
commit d402a1c96a
9 changed files with 89 additions and 22 deletions

View File

@ -3,3 +3,4 @@ pnpm-workspace.yaml
LICENCE LICENCE
dist dist
src/kotlin

4
dist/gkd.json vendored
View File

@ -1,8 +1,8 @@
{ {
"name": "GKD官方订阅", "name": "GKD官方订阅",
"version": 5, "version": 6,
"author": "lisonge", "author": "lisonge",
"supportUrl": "https://github.com/lisonge/gkd-subscription", "supportUrl": "https://github.com/gkd-kit/subscription",
"apps": [ "apps": [
{ {
"id": "air.tv.douyu.android", "id": "air.tv.douyu.android",

View File

@ -1,9 +1,10 @@
{ {
"name": "@gkd-kit/subscription", "name": "@gkd-kit/subscription",
"type": "module", "type": "module",
"version": "0.0.5", "version": "0.0.6",
"private": false,
"main": "./dist/gkd.json", "main": "./dist/gkd.json",
"unpkg": "./dist/gkd.json",
"jsdelivr": "./dist/gkd.json",
"files": [ "files": [
"dist" "dist"
], ],
@ -11,18 +12,29 @@
"build": "tsx ./src/main.ts" "build": "tsx ./src/main.ts"
}, },
"dependencies": { "dependencies": {
"@gkd-kit/selector": "0.0.3",
"@types/lodash": "^4.14.194", "@types/lodash": "^4.14.194",
"@types/node": "^20", "@types/node": "^20",
"@types/prettier": "2.7.3", "@types/prettier": "2.7.3",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"dotenv": "16.2.0", "dotenv": "^16.2.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"prettier": "2.8.8", "prettier": "^2.8.8",
"qiniu": "7.8.0", "qiniu": "^7.8.0",
"tsx": "^3.12.6", "tsx": "^3.12.6",
"typescript": "^5.0.4", "typescript": "^5.0.4",
"undici": "^5.22.1" "undici": "^5.22.1"
}, },
"author": "lisonge",
"license": "MIT",
"homepage": "https://github.com/gkd-kit/subscription#readme",
"bugs": {
"url": "https://github.com/gkd-kit/subscription/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/gkd-kit/subscription.git"
},
"volta": { "volta": {
"node": "20.3.0" "node": "20.3.0"
} }

View File

@ -1,10 +1,13 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings: settings:
autoInstallPeers: true autoInstallPeers: false
excludeLinksFromLockfile: false excludeLinksFromLockfile: false
dependencies: dependencies:
'@gkd-kit/selector':
specifier: 0.0.3
version: 0.0.3
'@types/lodash': '@types/lodash':
specifier: ^4.14.194 specifier: ^4.14.194
version: 4.14.194 version: 4.14.194
@ -18,16 +21,16 @@ dependencies:
specifier: ^1.11.7 specifier: ^1.11.7
version: 1.11.7 version: 1.11.7
dotenv: dotenv:
specifier: 16.2.0 specifier: ^16.2.0
version: 16.2.0 version: 16.2.0
lodash: lodash:
specifier: ^4.17.21 specifier: ^4.17.21
version: 4.17.21 version: 4.17.21
prettier: prettier:
specifier: 2.8.8 specifier: ^2.8.8
version: 2.8.8 version: 2.8.8
qiniu: qiniu:
specifier: 7.8.0 specifier: ^7.8.0
version: 7.8.0 version: 7.8.0
tsx: tsx:
specifier: ^3.12.6 specifier: ^3.12.6
@ -36,7 +39,7 @@ dependencies:
specifier: ^5.0.4 specifier: ^5.0.4
version: 5.0.4 version: 5.0.4
undici: undici:
specifier: 5.22.1 specifier: ^5.22.1
version: 5.22.1 version: 5.22.1
packages: packages:
@ -260,6 +263,10 @@ packages:
dev: false dev: false
optional: true optional: true
/@gkd-kit/selector@0.0.3:
resolution: {integrity: sha512-CXpUQ38F0CWtsKgbL4hzitGCPvIHeDFPCUvNjjAuyrd/55ODbJxzFe0OQ6LzLoFimklNNZ8MOe2tJHIhxnNZ0A==}
dev: false
/@tootallnate/once@1.1.2: /@tootallnate/once@1.1.2:
resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
engines: {node: '>= 6'} engines: {node: '>= 6'}

View File

@ -4,12 +4,17 @@ import fs from 'node:fs/promises';
import path from 'node:path'; import path from 'node:path';
import url from 'node:url'; import url from 'node:url';
import selfPkg from '../package.json'; import selfPkg from '../package.json';
import type { SubscriptionConfig } from './types'; import type { SubscriptionConfig, IArray } from './types';
import { parseSelector } from './selector';
export const relativePath = (p: string) => { export const relativePath = (p: string) => {
return url.fileURLToPath(new URL(p, import.meta.url)); return url.fileURLToPath(new URL(p, import.meta.url));
}; };
const iArrayToArray = <T>(array: IArray<T> = []): T[] => {
return Array<T>().concat(array);
};
export const writeConfig = async (fp: string, config: SubscriptionConfig) => { export const writeConfig = async (fp: string, config: SubscriptionConfig) => {
const filePath = relativePath(fp); const filePath = relativePath(fp);
const newConfig: SubscriptionConfig = { ...config }; const newConfig: SubscriptionConfig = { ...config };
@ -41,6 +46,36 @@ export const writeConfig = async (fp: string, config: SubscriptionConfig) => {
}); });
}); });
newConfig.apps?.forEach((app) => {
app.groups?.forEach((g) => {
if (!g.rules) return;
const rules = iArrayToArray(g.rules).map((r) => {
if (typeof r == 'string') {
return { matches: r };
}
return r;
});
rules.forEach((r) => {
[r.matches, r.excludeMatches]
.map((m) => iArrayToArray(m))
.flat()
.forEach((selector) => {
try {
parseSelector(selector);
} catch (e) {
console.error({
message: `invalid selector`,
appId: app.id,
groupKey: g.key,
selector,
});
throw e;
}
});
});
});
});
const sortKeys: (keyof SubscriptionConfig)[] = [ const sortKeys: (keyof SubscriptionConfig)[] = [
`name`, `name`,
`version`, `version`,

View File

@ -1,17 +1,19 @@
import { relativePath, walk, writeConfig } from './file'; import { relativePath, walk, writeConfig } from './file';
import { AppConfig, AppConfigMudule } from './types'; import { AppConfig, AppConfigMudule } from './types';
import url from 'node:url';
const apps: AppConfig[] = []; const apps: AppConfig[] = [];
for await (const tsFp of walk(relativePath('./apps'))) { for await (const tsFp of walk(relativePath('./apps'))) {
const mod: AppConfigMudule = await import(`file://` + tsFp); const mod: AppConfigMudule = await import(url.pathToFileURL(tsFp).href);
apps.push(mod.default); apps.push(mod.default);
} }
// a,b,c,d // a,b,c,d
apps.sort((a, b) => (a.id > b.id ? 1 : -1)); apps.sort((a, b) => (a.id > b.id ? 1 : -1));
await writeConfig(`../dist/gkd.json`, { await writeConfig(`../dist/gkd.json`, {
name: `GKD官方订阅`, name: `GKD官方订阅`,
author: `lisonge`, author: `lisonge`,
supportUrl: `https://github.com/lisonge/gkd-subscription`, supportUrl: `https://github.com/gkd-kit/subscription`,
apps, apps,
}); });

7
src/selector.ts Normal file
View File

@ -0,0 +1,7 @@
import SelectorKit from '@gkd-kit/selector';
const { CommonSelector } = SelectorKit.li.songe.selector;
export const parseSelector = (source: string) => {
return CommonSelector.Companion.parse(source);
};

View File

@ -1,4 +1,4 @@
type IArray<T> = T | T[]; export type IArray<T> = T | T[];
export type SubscriptionConfig = { export type SubscriptionConfig = {
name?: string; name?: string;
@ -20,7 +20,7 @@ export type SubscriptionConfig = {
type NumberFilter = {}; type NumberFilter = {};
type StringFilter = {}; type StringFilter = {};
type AutoProps = { type CommonProps = {
activityIds?: IArray<string>; activityIds?: IArray<string>;
excludeActivityIds?: IArray<string>; excludeActivityIds?: IArray<string>;
cd?: number; cd?: number;
@ -42,7 +42,7 @@ type AutoProps = {
export type AppConfig = { export type AppConfig = {
id: string; id: string;
groups?: GroupConfig[]; groups?: GroupConfig[];
} & AutoProps; } & CommonProps;
export type AppConfigMudule = { export type AppConfigMudule = {
default: AppConfig; default: AppConfig;
@ -53,16 +53,15 @@ type GroupConfig = {
name: string; name: string;
desc?: string; desc?: string;
rules?: IArray<RuleConfig | string>; rules?: IArray<RuleConfig | string>;
} & AutoProps; } & CommonProps;
type RuleConfig = { type RuleConfig = {
key?: number;
name?: string; name?: string;
desc?: string; desc?: string;
matches?: IArray<string>; matches?: IArray<string>;
excludeMatches?: IArray<string>; excludeMatches?: IArray<string>;
preKeys?: IArray<number>; preKeys?: IArray<number>;
} & AutoProps; } & CommonProps;
export const defineSubsConfig = (config: SubscriptionConfig) => { export const defineSubsConfig = (config: SubscriptionConfig) => {
return JSON.stringify(config, undefined, 2); return JSON.stringify(config, undefined, 2);

View File

@ -13,5 +13,9 @@
"strict": true, "strict": true,
"skipLibCheck": true "skipLibCheck": true
}, },
"include": ["./src/**/*.ts", "./scripts/**/*.ts", "./types/**/*.ts"] "include": [
"./src/**/*.{ts,js,mjs,cjs}",
"./scripts/**/*.ts",
"./types/**/*.ts"
]
} }