Files
batch-prompts/prompts/src/services/pb.service.ts
2026-01-10 16:58:15 +08:00

174 lines
4.0 KiB
TypeScript

import PocketBase from 'pocketbase';
import { EventEmitter } from 'eventemitter3'
type PBOptions = {
url: string;
token?: string;
}
export class PBCore {
declare client: PocketBase;
emitter = new EventEmitter();
token?: string;
constructor(options: PBOptions) {
this.client = new PocketBase(options.url);
this.token = options.token || '';
if (this.token) {
this.client.authStore.save(this.token);
}
}
async loginByPassword(email: string, password: string, admin: boolean = true) {
const collectionName = admin ? '_superusers' : 'users';
const authData = await this.client.collection(collectionName).authWithPassword(email, password);
this.emitter.emit('login', authData);
return authData;
}
async login({ username, password, admin = true }: { username: string; password: string, admin?: boolean }) {
if (this.client.authStore.isValid) {
return true;
}
try {
await this.loginByPassword(username, password, admin);
return true;
} catch (error) {
console.error('PocketBase login error:', error);
return false;
}
}
/**
*
* https://pocketbase.io/docs/api-collections/#create-collection
*
* */
async createCollection({ name, type, fields }: CreateCollection) {
const collections = await this.client.collections.getFullList();
const existing = collections.find(c => c.name === name);
if (existing) {
const collection = this.client.collection(name);
const schema = await this.client.collections.getOne(name);
return {
schema: schema,
existing: true,
collection
};
}
const schema = await this.client.collections.create({
name,
type: type ?? 'base',
fields: fields ?? defaultFields,
});
const collection = this.client.collection(name);
return {
collection,
schema
}
}
}
export const defaultFields: CollectionFields[] = [
{
name: 'title',
type: 'text',
},
{
name: 'summary',
type: 'text',
},
{
name: 'description',
type: 'text',
},
{
name: 'tags',
type: 'json',
},
{
name: 'data',
type: 'json',
},
{
name: 'status',
type: 'text',
},
{
name: 'created',
type: 'autodate',
onCreate: true,
},
{
name: 'updated',
type: 'autodate',
onCreate: true,
onUpdate: true,
}
]
export type CollectionFields = {
name: string;
type: string;
required?: boolean;
options?: any;
onCreate?: boolean;
onUpdate?: boolean;
}
export type CreateCollectioRule = {
listRule?: string;
viewRule?: string;
/**
* createRule: 'id = @request.auth.id',
*/
createRule?: string;
updateRule?: string;
deleteRule?: string;
}
export type CreateCollection = {
name: string;
type?: 'base' | 'viwer' | 'auth';
fields?: CollectionFields[];
/**
* viewer:
* viewQuery: 'SELECT id, name from posts',
*/
viewQuery?: string;
} & CreateCollectioRule;
export class PBService extends PBCore {
collectionName = 'images_generation_tasks';
constructor(options: PBOptions) {
super(options);
this.client.autoCancellation(false)
}
getCollection<T>(name: string) {
return this.client.collection<T>(name);
}
async initPbService() {
const isLogin = this.client.authStore.isValid;
console.log('PocketBase is logged in:', isLogin);
}
async importData(data: any[]) {
const collection = this.getCollection(this.collectionName);
for (const item of data) {
await collection.create(item);
}
}
get collection() {
return this.client.collection<ImageCollection>(this.collectionName);
}
}
const ImageTaskStatus = ['提示词优化中', '计划中', '生成图片中', '图片下载中', '暂停中', '已完成', '失败'] as const;
type Data<T = {}> = {
images: { type: 'jimeng' | 'tos', url: string }[];
} & T
export type ImageCollection<T = any> = {
id: string;
created: string;
updated: string;
title: string;
tags: any;
summary: string;
description: string;
data: Data<T>;
status: typeof ImageTaskStatus[number];
}