Started filtering system
This commit is contained in:
Generated
+31
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.16.7",
|
||||
"version": "1.16.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "materialious",
|
||||
"version": "1.16.7",
|
||||
"version": "1.16.8",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@capacitor-community/electron": "^5.0.1",
|
||||
@@ -49,6 +49,7 @@
|
||||
"mysql2": "^3.18.2",
|
||||
"pg": "^8.19.0",
|
||||
"pg-hstore": "^2.3.4",
|
||||
"safe-regex2": "^5.0.0",
|
||||
"sequelize": "^6.37.7",
|
||||
"shaka-player": "^4.16.14",
|
||||
"sponsorblock-api": "^0.2.4",
|
||||
@@ -16051,6 +16052,15 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ret": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz",
|
||||
"integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
|
||||
@@ -16287,6 +16297,25 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-regex2": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz",
|
||||
"integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ret": "~0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"mysql2": "^3.18.2",
|
||||
"pg": "^8.19.0",
|
||||
"pg-hstore": "^2.3.4",
|
||||
"safe-regex2": "^5.0.0",
|
||||
"sequelize": "^6.37.7",
|
||||
"shaka-player": "^4.16.14",
|
||||
"sponsorblock-api": "^0.2.4",
|
||||
@@ -98,4 +99,4 @@
|
||||
"youtubei.js": "^16.0.1",
|
||||
"zod": "^4.3.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { videoLength } from '$lib/numbers';
|
||||
import { generateChapterWebVTT, type ParsedDescription } from '$lib/description';
|
||||
import { Capacitor, SystemBars, SystemBarsStyle, SystemBarType } from '@capacitor/core';
|
||||
import { error, type Page } from '@sveltejs/kit';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import Mousetrap from 'mousetrap';
|
||||
import { CapacitorMusicControls } from 'capacitor-music-controls-plugin';
|
||||
import shaka from 'shaka-player/dist/shaka-player.ui';
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { z } from 'zod';
|
||||
import type { FeedItem } from './feed';
|
||||
import isSafeRegex from 'safe-regex2';
|
||||
|
||||
const zFilterOperatorEnum = z.enum([
|
||||
'equals', // equal to
|
||||
'in', // in a set of values
|
||||
'like', // contains (string matching)
|
||||
'gt', // greater than
|
||||
'lt', // less than
|
||||
'regex' // regular expression matching
|
||||
]);
|
||||
|
||||
// Filter condition schema
|
||||
const zFilterCondition = z.object({
|
||||
field: z.string(), // Field to filter
|
||||
operator: zFilterOperatorEnum, // Operator
|
||||
value: z.union([
|
||||
// Value to compare against
|
||||
z.string(),
|
||||
z.number(),
|
||||
z.array(z.string()),
|
||||
z.array(z.number()),
|
||||
z.string().regex(/.*/)
|
||||
])
|
||||
});
|
||||
|
||||
// Logical grouping operator
|
||||
const zFilterGroup = z.object({
|
||||
conditions: z.array(zFilterCondition), // A list of conditions to apply
|
||||
operator: z.enum(['AND', 'OR']).optional() // Logical grouping of conditions
|
||||
});
|
||||
|
||||
const zBlockListSchema = z.array(zFilterGroup);
|
||||
|
||||
export function filterByBlocklist<T extends FeedItem>(
|
||||
data: T[],
|
||||
blocklist: z.infer<typeof zBlockListSchema>
|
||||
): T[] {
|
||||
return data.filter((item) => {
|
||||
return blocklist.every((filterGroup) => {
|
||||
return filterGroup.conditions.every((condition) => {
|
||||
const fieldValue = item[condition.field as keyof T];
|
||||
|
||||
switch (condition.operator) {
|
||||
case 'equals':
|
||||
return fieldValue === condition.value;
|
||||
case 'in':
|
||||
return (
|
||||
Array.isArray(condition.value) && (condition.value as any[]).includes(fieldValue)
|
||||
);
|
||||
case 'like':
|
||||
return (
|
||||
typeof fieldValue === 'string' &&
|
||||
typeof condition.value === 'string' &&
|
||||
fieldValue.includes(condition.value)
|
||||
);
|
||||
case 'gt':
|
||||
return (
|
||||
typeof fieldValue === 'number' &&
|
||||
typeof condition.value === 'number' &&
|
||||
fieldValue > condition.value
|
||||
);
|
||||
case 'lt':
|
||||
return (
|
||||
typeof fieldValue === 'number' &&
|
||||
typeof condition.value === 'number' &&
|
||||
fieldValue < condition.value
|
||||
);
|
||||
case 'regex':
|
||||
if (typeof condition.value !== 'string' || !isSafeRegex(condition.value)) return false;
|
||||
return typeof fieldValue === 'string' && new RegExp(condition.value).test(fieldValue);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
</style>
|
||||
</svelte:head>
|
||||
|
||||
{#await navigating.completed}
|
||||
{#await navigating.complete}
|
||||
<PageLoading />
|
||||
<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
|
||||
{:then _}
|
||||
|
||||
Reference in New Issue
Block a user