small refactoring

This commit is contained in:
Egor Aristov 2025-05-06 23:35:28 +03:00
parent 129e95f556
commit 89f081f0ed
Signed by: egor3f
GPG Key ID: 40482A264AAEC85F
3 changed files with 23 additions and 27 deletions

View File

@ -1,5 +1,5 @@
import {defineStore} from "pinia";
import {emptySpecs, type SpecField, fields, type Specs, type SpecValue} from "@/urlmaker/specs.ts";
import {defaultSpecs, type SpecField, fields, type Specs, type SpecValue} from "@/urlmaker/specs.ts";
import {computed, reactive} from "vue";
import {debounce} from "es-toolkit";
@ -8,7 +8,7 @@ const LOCAL_STORAGE_KEY = 'rssalchemy_store_wizard';
export const useWizardStore = defineStore('wizard', () => {
const locStorageContent = localStorage.getItem(LOCAL_STORAGE_KEY);
const initialSpecs = locStorageContent ? JSON.parse(locStorageContent) as Specs : emptySpecs;
const initialSpecs = locStorageContent ? JSON.parse(locStorageContent) as Specs : defaultSpecs;
const specs = reactive(Object.assign({}, initialSpecs));
@ -23,7 +23,7 @@ export const useWizardStore = defineStore('wizard', () => {
}, 100);
function updateSpec(fieldName: keyof Specs, newValue: SpecValue) {
specs[fieldName] = newValue;
(specs as Record<keyof Specs, SpecValue>)[fieldName] = newValue;
updateLocalStorage();
}
function updateSpecs(newValue: Specs) {
@ -31,7 +31,7 @@ export const useWizardStore = defineStore('wizard', () => {
updateLocalStorage();
}
function reset() {
Object.assign(specs, emptySpecs);
Object.assign(specs, defaultSpecs);
updateLocalStorage();
}

View File

@ -1,6 +1,6 @@
import type {Specs} from "@/urlmaker/specs.ts";
import {type Specs} from "@/urlmaker/specs.ts";
import {b64decode, b64encode, compress, decompress, decompressString} from "@/urlmaker/utils.ts";
import {rssalchemy as pb} from '@/urlmaker/proto/specs.ts';
import {rssalchemy, rssalchemy as pb} from '@/urlmaker/proto/specs.ts';
const apiBase = import.meta.env.VITE_API_BASE || document.location.origin;
const renderEndpoint = '/api/v1/render/'; // trailing slash
@ -57,7 +57,7 @@ export async function encodePreset(specs: Specs): Promise<string> {
}
export async function encodeSpecsPart(specs: Specs): Promise<string> {
const pbSpecs = pb.Specs.fromObject(specs);
const pbSpecs = pb.Specs.fromObject(specs as ReturnType<rssalchemy.Specs['toObject']>);
let data = pbSpecs.serializeBinary();
data = await compress(data);
const encodedData = b64encode(data);

View File

@ -8,9 +8,23 @@ import {
import {rssalchemy} from "@/urlmaker/proto/specs.ts";
import type {Enum} from "@/common/enum.ts";
export type SpecKey = ReturnType<rssalchemy.Specs['toObject']>;
export const defaultSpecs = {
url: '',
selector_post: '',
selector_title: '',
selector_link: '',
selector_description: '',
selector_author: '',
selector_content: '',
selector_enclosure: '',
selector_created: '',
created_extract_from: rssalchemy.ExtractFrom.InnerText,
created_attribute_name: '',
cache_lifetime: '10m'
};
export type SpecValue = string | number;
export type Specs = {[k in keyof SpecKey]: SpecValue};
export type Specs = typeof defaultSpecs;
export enum InputType {
Url = 'url',
@ -23,7 +37,6 @@ export interface SpecField {
input_type: InputType
enum?: Enum,
label: string
default: SpecValue
validate: validator
required?: boolean
group?: string
@ -35,7 +48,6 @@ export const fields: SpecField[] = [
name: 'url',
input_type: InputType.Url,
label: 'URL of page for converting',
default: '',
validate: validateUrl,
required: true,
},
@ -43,35 +55,30 @@ export const fields: SpecField[] = [
name: 'selector_post',
input_type: InputType.Text,
label: 'CSS Selector for post',
default: '',
validate: validateSelector,
},
{
name: 'selector_title',
input_type: InputType.Text,
label: 'CSS Selector for title',
default: '',
validate: validateSelector,
},
{
name: 'selector_link',
input_type: InputType.Text,
label: 'CSS Selector for link',
default: '',
validate: validateSelector,
},
{
name: 'selector_description',
input_type: InputType.Text,
label: 'CSS Selector for description',
default: '',
validate: validateSelector,
},
{
name: 'selector_author',
input_type: InputType.Text,
label: 'CSS Selector for author',
default: '',
validate: validateSelector,
},
@ -79,7 +86,6 @@ export const fields: SpecField[] = [
name: 'selector_created',
input_type: InputType.Text,
label: 'CSS Selector for created date',
default: '',
validate: validateSelector,
group: 'created',
},
@ -91,7 +97,6 @@ export const fields: SpecField[] = [
{label: 'Attribute', value: rssalchemy.ExtractFrom.Attribute},
],
label: 'Extract from',
default: rssalchemy.ExtractFrom.InnerText,
validate: value => Object.values(rssalchemy.ExtractFrom).includes(value),
group: 'created',
show_if: specs => !!specs.selector_created,
@ -100,7 +105,6 @@ export const fields: SpecField[] = [
name: 'created_attribute_name',
input_type: InputType.Text,
label: 'Attribute name',
default: '',
validate: validateAttribute,
show_if: specs =>
!!specs.selector_created && specs.created_extract_from === rssalchemy.ExtractFrom.Attribute,
@ -111,26 +115,18 @@ export const fields: SpecField[] = [
name: 'selector_content',
input_type: InputType.Text,
label: 'CSS Selector for content',
default: '',
validate: validateSelector,
},
{
name: 'selector_enclosure',
input_type: InputType.Text,
label: 'CSS Selector for enclosure (e.g. image url)',
default: '',
validate: validateSelector,
},
{
name: 'cache_lifetime',
input_type: InputType.Text,
label: 'Cache lifetime (format examples: 10s, 1m, 2h)',
default: '10m',
validate: validateDuration,
},
];
export const emptySpecs = fields.reduce((o, f) => {
o[f.name] = f.default;
return o
}, {} as Specs);