This commit is contained in:
Dragurimu 2022-08-09 22:16:39 -05:00
parent 4b8c59bcff
commit 93f40d22e9
24 changed files with 1092 additions and 80 deletions

View File

@ -1,5 +1,7 @@
# @biscuitland/api-types
## Most importantly, api-types is:
1:1 type definitions package for the [Discord](https://discord.com/developers/docs/intro) API.
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
@ -23,7 +25,7 @@ import type { DiscordUser } from '@biscuitland/api-types';
## Example for [Deno](https://deno.land/)
```ts
import type { DiscordUser } from "https://unpkg.com/@biscuitland/api-types@1.2.0/dist/index.d.ts";
import type { DiscordUser } from "https://unpkg.com/@biscuitland/api-types@1.3.1/dist/index.d.ts";
```
We deliver this package through [unpkg](https://unpkg.com/) and it does contain constants and routes too

View File

@ -1,6 +1,6 @@
{
"name": "@biscuitland/api-types",
"version": "1.3.0",
"version": "1.3.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",

View File

@ -5,7 +5,7 @@ export const BASE_URL = 'https://discord.com/api';
export const API_VERSION = 10;
/** https://github.com/oasisjs/biscuit/releases */
export const BISCUIT_VERSION = '1.2.0';
export const BISCUIT_VERSION = '1.3.1';
/** https://discord.com/developers/docs/reference#user-agent */
export const USER_AGENT = `DiscordBot (https://github.com/oasisjs/biscuit, v${BISCUIT_VERSION})`;

View File

@ -1,11 +1,13 @@
# @biscuitland/cache
Structures to create a custom cache completely decoupled from the rest of the library. You can choose to use a `MemoryCacheAdapter` or a `RedisCacheAdapter` according to your needs.
In progress.
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
[<img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white">](https://discord.gg/XNw2RZFzaP)
## Links
* [Website](https://biscuitjs.com/)
* [Documentation](https://docs.biscuitjs.com/)
* [Discord](https://discord.gg/XNw2RZFzaP)
* [core](https://www.npmjs.com/package/@biscuitland/core) | [api-types](https://www.npmjs.com/package/@biscuitland/api-types) | [rest](https://www.npmjs.com/package/@biscuitland/rest) | [ws](https://www.npmjs.com/package/@biscuitland/ws) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)
- [Website](https://biscuitjs.com/)
- [Documentation](https://docs.biscuitjs.com/)
- [Discord](https://discord.gg/XNw2RZFzaP)
- [core](https://www.npmjs.com/package/@biscuitland/core) | [api-types](https://www.npmjs.com/package/@biscuitland/api-types) | [rest](https://www.npmjs.com/package/@biscuitland/rest) | [ws](https://www.npmjs.com/package/@biscuitland/ws) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)

View File

@ -1,6 +1,6 @@
{
"name": "@biscuitland/cache",
"version": "1.3.0",
"version": "1.3.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
@ -23,7 +23,7 @@
}
},
"dependencies": {
"@biscuitland/api-types": "^1.2.0",
"@biscuitland/api-types": "^1.3.1",
"ioredis": "^5.2.2"
},
"devDependencies": {

View File

@ -3,29 +3,48 @@ export interface CacheAdapter {
* @inheritDoc
*/
get<T = unknown>(name: string): Promise<T | unknown>;
get(id: string): any | Promise<any>;
get(id: string, guild?: string): string | Promise<string>;
/**
* @inheritDoc
*/
set(name: string, data: unknown): Promise<void>;
set(id: string, data: any, expire?: number): void | Promise<void>;
/**
* @inheritDoc
*/
remove(name: string): Promise<void>;
count(to: string): number | Promise<number>;
/**
* @inheritDoc
*/
clear(): Promise<void>;
remove(id: string): void | Promise<void>;
/**
* @inheritDoc
*/
close?(): Promise<void>;
contains(to: string, id: string): boolean | Promise<boolean>;
/**
* @inheritDoc
*/
getToRelationship(to: string): string[] | Promise<string[]>;
/**
* @inheritDoc
*/
addToRelationship(to: string, id: string): void | Promise<void>;
/**
* @inheritDoc
*/
removeToRelationship(to: string, id: string): void | Promise<void>;
}

View File

@ -1,51 +1,119 @@
import { CacheAdapter } from './cache-adapter';
import type { CacheAdapter } from './cache-adapter';
interface Options {
expire?: number;
}
export class MemoryCacheAdapter implements CacheAdapter {
/**
* @inheritDoc
*/
private static readonly DEFAULTS = {
};
private readonly data = new Map<string, any>();
private readonly relationships = new Map<string, string[]>();
private readonly storage = new Map<string, { data: any; expire?: number }>();
readonly options: Options;
constructor(options?: Options) {
this.options = Object.assign(MemoryCacheAdapter.DEFAULTS, options);
}
/**
* @inheritDoc
*/
async get<T = unknown>(name: string): Promise<T | null> {
const data = this.data.get(name);
get<T = any>(id: string): T | null {
const data = this.storage.get(id);
if (!data) {
return null;
if (data) {
if (data.expire && data.expire < Date.now()) {
this.storage.delete(id);
} else {
return JSON.parse(data.data);
}
}
return JSON.parse(data);
return null;
}
/**
* @inheritDoc
*/
async set(name: string, data: unknown): Promise<void> {
const stringData = JSON.stringify(data, (_, v) =>
typeof v === 'bigint' ? v.toString() : v
);
this.data.set(name, stringData);
set(id: string, data: any, expire = this.options.expire): void {
if (expire) {
this.storage.set(id, { data: JSON.stringify(data), expire: Date.now() + expire });
} else {
this.storage.set(id, { data: JSON.stringify(data) });
}
}
/**
* @inheritDoc
*/
async remove(name: string): Promise<void> {
this.data.delete(name);
count(to: string): number {
return this.getToRelationship(to).length;
}
/**
* @inheritDoc
*/
async clear(): Promise<void> {
this.data.clear();
remove(id: string): void {
this.storage.delete(id);
}
/**
* @inheritDoc
*/
contains(to: string, id: string): boolean {
return this.getToRelationship(to).includes(id);
}
/**
* @inheritDoc
*/
getToRelationship(to: string): string[] {
return this.relationships.get(to) || [];
}
/**
* @inheritDoc
*/
addToRelationship(to: string, id: string): void {
const data = this.getToRelationship(to);
if (data.includes(id)) {
return;
}
data.push(id);
const has = !!this.relationships.get(to);
if (!has) {
this.relationships.set(to, data);
}
}
/**
* @inheritDoc
*/
removeToRelationship(to: string, id: string): void {
const data = this.getToRelationship(to);
if (data) {
const idx = data.indexOf(id);
if (idx === -1) {
return;
}
data.splice(idx, 1);
}
}
}

View File

@ -1,28 +1,29 @@
import type { Redis, RedisOptions } from 'ioredis';
import type { CacheAdapter } from './cache-adapter';
import { CacheAdapter } from './cache-adapter';
import Redis, { RedisOptions } from 'ioredis';
import IORedis from 'ioredis';
export interface BaseOptions {
prefix?: string;
interface BaseOptions {
namespace: string;
expire?: number;
}
export interface BuildOptions extends BaseOptions, RedisOptions {}
interface BuildOptions extends BaseOptions, RedisOptions { }
export interface ClientOptions extends BaseOptions {
interface ClientOptions extends BaseOptions {
client: Redis;
}
export type Options = BuildOptions | ClientOptions;
type Options = BuildOptions | ClientOptions;
export class RedisCacheAdapter implements CacheAdapter {
static readonly DEFAULTS = {
prefix: 'biscuitland',
private static readonly DEFAULTS = {
namespace: 'biscuitland'
};
private readonly client: Redis;
options: Options;
readonly options: Options;
constructor(options?: Options) {
this.options = Object.assign(RedisCacheAdapter.DEFAULTS, options);
@ -35,17 +36,12 @@ export class RedisCacheAdapter implements CacheAdapter {
}
}
_getPrefix(name: string) {
return `${this.options.prefix}:${name}`;
}
/**
* @inheritDoc
*/
async get<T = unknown>(name: string): Promise<T | null> {
const completKey = this._getPrefix(name);
const data = await this.client.get(completKey);
async get(id: string): Promise<any> {
const data = await this.client.get(this.composite(id));
if (!data) {
return null;
@ -58,38 +54,67 @@ export class RedisCacheAdapter implements CacheAdapter {
* @inheritDoc
*/
async set(name: string, data: unknown): Promise<void> {
const stringData = JSON.stringify(data, (_, v) =>
typeof v === 'bigint' ? v.toString() : v
);
const completeKey = this._getPrefix(name);
await this.client.set(completeKey, stringData);
async set(id: string, data: unknown, expire = this.options.expire): Promise<void> {
if (expire) {
await this.client.set(this.composite(id), JSON.stringify(data), 'EX', expire);
} else {
await this.client.set(this.composite(id), JSON.stringify(data));
}
}
/**
* @inheritDoc
*/
async remove(name: string): Promise<void> {
const completKey = this._getPrefix(name);
await this.client.del(completKey);
async count(_to: string): Promise<number> {
throw new Error('Method not implemented.');
}
/**
* @inheritDoc
*/
async clear(): Promise<void> {
this.client.disconnect();
async remove(id: string): Promise<void> {
await this.client.del(this.composite(id));
}
/**
* @inheritDoc
*/
async close(): Promise<void> {
this.client.disconnect();
async contains(_to: string, _id: string): Promise<boolean> {
throw new Error('Method not implemented.');
}
}
/**
* @inheritDoc
*/
async getToRelationship(_to: string): Promise<string[]> {
throw new Error('Method not implemented.');
}
/**
* @inheritDoc
*/
async addToRelationship(_to: string, _id: string): Promise<void> {
throw new Error('Method not implemented.');
}
/**
* @inheritDoc
*/
async removeToRelationship(_to: string, _id: string): Promise<void> {
throw new Error('Method not implemented.');
}
/**
* @inheritDoc
*/
composite(id: string): string {
return `${this.options.namespace}:${id}`;
}
}

215
packages/cache/src/cache.ts vendored Normal file
View File

@ -0,0 +1,215 @@
import { MemoryCacheAdapter } from './adapters/memory-cache-adapter';
// import { RedisCacheAdapter } from './adapters/redis-cache-adapter';
import {
ChannelResource,
GuildEmojiResource,
GuildMemberResource,
GuildResource,
GuildRoleResource,
GuildStickerResource,
UserResource,
VoiceResource
} from './resources';
/**
* add options and adaptor passable by options
* @default MemoryCacheAdapter
*/
/**
* Add more adapters and options
* Allow passing customizable resources and deleting resources
*/
/**
* Add presence system (disabled by default)
* Add TTL option (default 7 days)
* Add permissions resource (accessible as a subResource)
*/
export class Cache {
readonly channels: ChannelResource;
readonly emojis: GuildEmojiResource;
readonly members: GuildMemberResource;
readonly guilds: GuildResource;
readonly roles: GuildRoleResource;
readonly stickers: GuildStickerResource;
readonly users: UserResource;
readonly voices: VoiceResource;
ready: boolean;
constructor() {
this.ready = false;
/** this change to memory */
const adapter = new MemoryCacheAdapter();
this.channels = new ChannelResource(adapter);
this.emojis = new GuildEmojiResource(adapter);
this.members = new GuildMemberResource(adapter);
this.guilds = new GuildResource(adapter);
this.roles = new GuildRoleResource(adapter);
this.stickers = new GuildStickerResource(adapter);
this.users = new UserResource(adapter);
this.voices = new VoiceResource(adapter);
}
/**
* @inheritDoc
*/
async start(event: { t: string; d: any }) {
switch (event.t) {
case 'READY':
await this.users.set(event.d.user.id, event.d.user);
const guilds: Array<Promise<any> | undefined> = [];
for (const guild of event.d.guilds) {
guilds.push(this.guilds.set(guild.id, guild));
}
await Promise.all(guilds);
this.ready = true;
break;
case 'USER_UPDATE':
await this.users.set(event.d.id, event.d);
break;
case 'GUILD_CREATE':
await this.guilds.set(event.d.id, event.d);
break;
case 'GUILD_UPDATE':
this.guilds.set(event.d.id, event.d);
break;
case 'GUILD_DELETE':
if (event.d.unavailable) {
await this.guilds.set(event.d.id, event.d);
} else {
await this.guilds.remove(event.d.id);
}
break;
case 'CHANNEL_CREATE':
// modify [Add elimination system]
await this.channels.set(event.d.id, event.d);
break;
case 'CHANNEL_UPDATE':
// modify [Add elimination system]
await this.channels.set(event.d.id, event.d);
break;
case 'CHANNEL_DELETE':
// modify [Add elimination system]
await this.channels.remove(event.d.id);
break;
case 'GUILD_ROLE_CREATE':
await this.roles.set(
event.d.role.id,
event.d.guild_id,
event.d.role
);
break;
case 'GUILD_ROLE_UPDATE':
await this.roles.set(
event.d.role.id,
event.d.guild_id,
event.d.role
);
break;
case 'GUILD_ROLE_DELETE':
await this.roles.remove(event.d.role.id, event.d.guild_id);
break;
case 'GUILD_EMOJIS_UPDATE':
// modify [Add elimination system]
for (const v of event.d.emojis) {
await this.emojis?.set(v.id, event.d.guild_id, v);
}
break;
case 'GUILD_STICKERS_UPDATE':
// modify [Add elimination system]
for (const v of event.d.stickers) {
await this.stickers?.set(v.id, event.d.guild_id, v);
}
break;
case 'GUILD_MEMBER_ADD':
await this.members.set(
event.d.user.id,
event.d.guild_id,
event.d
);
break;
case 'GUILD_MEMBER_UPDATE':
await this.members.set(
event.d.user.id,
event.d.guild_id,
event.d
);
break;
case 'GUILD_MEMBER_REMOVE':
await this.members.remove(event.d.user.id, event.d.guild_id);
break;
case 'GUILD_MEMBERS_CHUNK':
const members: Array<Promise<any> | undefined> = [];
for (const member of event.d.members) {
members.push(
this.members.set(
member.user.id,
event.d.guild_id,
member
)
);
}
await Promise.all(members);
break;
case 'VOICE_STATE_UPDATE':
if (!event.d.guild_id) {
return;
}
if (event.d.user_id && event.d.member) {
await this.members.set(
event.d.user_id,
event.d.guild_id,
event.d.member
);
}
if (event.d.channel_id != null) {
await this.voices.set(
event.d.user_id,
event.d.guild_id,
event.d
);
} else {
await this.voices.remove(event.d.user_id, event.d.guild_id);
}
break;
}
}
}

View File

@ -2,3 +2,5 @@ export { CacheAdapter } from './adapters/cache-adapter';
export { MemoryCacheAdapter } from './adapters/memory-cache-adapter';
export { RedisCacheAdapter } from './adapters/redis-cache-adapter';
export { Cache } from './cache';

View File

@ -0,0 +1,67 @@
import { CacheAdapter } from '../adapters/cache-adapter';
export class BaseResource {
namespace = 'base';
adapter!: CacheAdapter; // replace
constructor() {
//
}
/**
* @inheritDoc
*/
async count(to: string): Promise<number> {
return await this.adapter.count(this.hashId(to));
}
/**
* @inheritDoc
*/
async contains(to: string, id: string): Promise<boolean> {
return await this.adapter.contains(this.hashId(to), id);
}
/**
* @inheritDoc
*/
async getToRelationship(to: string): Promise<string[]> {
return await this.adapter.getToRelationship(this.hashId(to));
}
/**
* @inheritDoc
*/
async addToRelationship(to: string, id: string): Promise<void> {
await this.adapter.addToRelationship(this.hashId(to), id);
}
/**
* @inheritDoc // to-do replace
*/
async removeToRelationship(to: string, id: string): Promise<void> {
await this.adapter.removeToRelationship(this.hashId(to), id);
}
/**
* @inheritDoc
*/
hashId(id: string): string {
return `${this.namespace}.${id}`;
}
/**
* @inheritDoc
*/
hashGuildId(id: string, guild: string): string {
return `${this.namespace}.${guild}.${id}`;
}
}

View File

@ -0,0 +1,81 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordChannel } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class ChannelResource extends BaseResource {
namespace: 'channel' = 'channel';
adapter: CacheAdapter;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
}
/**
* @inheritDoc
*/
async get(id: string): Promise<DiscordChannel | null> {
const kv = await this.adapter.get(this.hashId(id));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc // to-do rework
*/
async set(id: string, data: any, expire?: number): Promise<void> {
delete data.recipients;
await this.addToRelationship(id);
await this.adapter.set(this.hashId(id), data, expire);
}
/**
* @inheritDoc
*/
async count(): Promise<number> {
return await this.adapter.count(this.namespace);
}
/**
* @inheritDoc
*/
async remove(id: string): Promise<void> {
await this.adapter.remove(this.hashId(id));
}
/**
* @inheritDoc
*/
async contains(id: string): Promise<boolean> {
return await this.adapter.contains(this.namespace, id);
}
/**
* @inheritDoc
*/
async getToRelationship(): Promise<string[]> {
return await this.adapter.getToRelationship(this.namespace);
}
/**
* @inheritDoc
*/
async addToRelationship(id: string): Promise<void> {
await this.adapter.addToRelationship(this.namespace, id);
}
}

View File

@ -0,0 +1,51 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordEmoji } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class GuildEmojiResource extends BaseResource {
namespace: 'emoji' = 'emoji';
adapter: CacheAdapter;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
}
/**
* @inheritDoc
*/
async get(id: string, guild: string): Promise<DiscordEmoji | null> {
const kv = await this.adapter.get(this.hashGuildId(id, guild));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(
id: string,
guild: string,
data: any,
expire?: number
): Promise<void> {
await this.adapter.set(this.hashGuildId(id, guild), data, expire);
}
/**
* @inheritDoc
*/
async remove(id: string, guild: string): Promise<void> {
await this.adapter.remove(this.hashGuildId(id, guild));
}
}

View File

@ -0,0 +1,72 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordMember } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
import { UserResource } from './user-resource';
export class GuildMemberResource extends BaseResource {
namespace: 'member' = 'member';
adapter: CacheAdapter;
users: UserResource;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
this.users = new UserResource(adapter);
}
/**
* @inheritDoc
*/
async get(
id: string,
guild: string
): Promise<(DiscordMember & { id: string }) | null> {
const kv = await this.adapter.get(this.hashGuildId(id, guild));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(
id: string,
guild: string,
data: any,
expire?: number
): Promise<void> {
if (!data.id) {
data.id = id;
}
if (data.user) {
await this.users.set(data.user.id, data.user);
}
if (!data.guild_id) {
data.guild_id = guild;
}
delete data.user;
await this.addToRelationship(id, guild);
await this.adapter.set(this.hashGuildId(id, guild), data, expire);
}
/**
* @inheritDoc
*/
async remove(id: string, guild: string): Promise<void> {
await this.adapter.remove(this.hashGuildId(id, guild));
}
}

View File

@ -0,0 +1,174 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordGuild } from '@biscuitland/api-types';
import { ChannelResource } from './channel-resource';
import { GuildEmojiResource } from './guild-emoji-resource';
import { GuildMemberResource } from './guild-member-resource';
import { GuildRoleResource } from './guild-role-resource';
import { GuildStickerResource } from './guild-sticker-resource';
import { VoiceResource } from './voice-resource';
import { BaseResource } from './base-resource';
export class GuildResource extends BaseResource {
namespace: 'guild' = 'guild';
adapter: CacheAdapter;
private channels: ChannelResource;
private emojis: GuildEmojiResource;
private members: GuildMemberResource;
private roles: GuildRoleResource;
private stickers: GuildStickerResource;
private voices: VoiceResource;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
this.channels = new ChannelResource(adapter);
this.emojis = new GuildEmojiResource(adapter);
this.members = new GuildMemberResource(adapter);
this.roles = new GuildRoleResource(adapter);
this.stickers = new GuildStickerResource(adapter);
this.voices = new VoiceResource(adapter);
}
/**
* @inheritDoc
*/
async get(id: string): Promise<DiscordGuild | null> {
const kv = await this.adapter.get(this.hashId(id));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(id: string, data: any, expire?: number): Promise<void> {
if (data.channels) {
const channels: Array<Promise<any> | undefined> = [];
for (const channel of data.channels) {
await this.channels.set(channel.id, channel);
}
await Promise.all(channels);
}
if (data.members) {
const members: Array<Promise<any> | undefined> = [];
for (const member of data.members) {
await this.members.set(member.user.id, id, member);
}
await Promise.all(members);
}
if (data.roles) {
const roles: Array<Promise<any> | undefined> = [];
for (const role of data.roles) {
await this.roles.set(role.id, id, role);
}
await Promise.all(roles);
}
if (data.stickers) {
const stickers: Array<Promise<any> | undefined> = [];
for (const sticker of data.stickers) {
await this.stickers.set(sticker.id, id, sticker);
}
await Promise.all(stickers);
}
if (data.emojis) {
const emojis: Array<Promise<any> | undefined> = [];
for (const emoji of data.emojis) {
await this.emojis.set(emoji.id, id, emoji);
}
await Promise.all(emojis);
}
if (data.voice_states) {
const voices: Array<Promise<any>> = [];
for (const voice of data.voice_states) {
if (!voice.guild_id) {
voice.guild_id = id;
}
voices.push(this.voices.set(voice.user_id, id, voice));
}
await Promise.all(voices);
}
delete data.channels;
delete data.members;
delete data.roles;
delete data.stickers;
delete data.emojis;
delete data.presences;
delete data.voice_states;
await this.addToRelationship(id);
await this.adapter.set(this.hashId(id), data, expire);
}
/**
* @inheritDoc
*/
async count(): Promise<number> {
return await this.adapter.count(this.namespace);
}
/**
* @inheritDoc
*/
async remove(id: string): Promise<void> {
await this.adapter.remove(this.hashId(id));
}
/**
* @inheritDoc
*/
async contains(id: string): Promise<boolean> {
return await this.adapter.contains(this.namespace, id);
}
/**
* @inheritDoc
*/
async getToRelationship(): Promise<string[]> {
return await this.adapter.getToRelationship(this.namespace);
}
/**
* @inheritDoc
*/
async addToRelationship(id: string): Promise<void> {
await this.adapter.addToRelationship(this.namespace, id);
}
}

View File

@ -0,0 +1,59 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordRole } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class GuildRoleResource extends BaseResource {
namespace: 'role' = 'role';
adapter: CacheAdapter;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
}
/**
* @inheritDoc
*/
async get(id: string, guild: string): Promise<DiscordRole | null> {
const kv = await this.adapter.get(this.hashGuildId(id, guild));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(
id: string,
guild: string,
data: any,
expire?: number
): Promise<void> {
if (!data.id) {
data.id = id;
}
if (!data.guild_id) {
data.guild_id = guild;
}
await this.adapter.set(this.hashGuildId(id, guild), data, expire);
}
/**
* @inheritDoc
*/
async remove(id: string, guild: string): Promise<void> {
await this.adapter.remove(this.hashGuildId(id, guild));
}
}

View File

@ -0,0 +1,59 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordSticker } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class GuildStickerResource extends BaseResource {
namespace: 'sticker' = 'sticker';
adapter: CacheAdapter;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
}
/**
* @inheritDoc
*/
async get(id: string, guild: string): Promise<DiscordSticker | null> {
const kv = await this.adapter.get(this.hashGuildId(id, guild));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(
id: string,
guild: string,
data: any,
expire?: number
): Promise<void> {
if (!data.id) {
data.id = id;
}
if (!data.guild_id) {
data.guild_id = guild;
}
await this.adapter.set(this.hashGuildId(id, guild), data, expire);
}
/**
* @inheritDoc
*/
async remove(id: string, guild: string): Promise<void> {
await this.adapter.remove(this.hashGuildId(id, guild));
}
}

13
packages/cache/src/resources/index.ts vendored Normal file
View File

@ -0,0 +1,13 @@
export { BaseResource } from './base-resource';
export { ChannelResource } from './channel-resource';
export { GuildEmojiResource } from './guild-emoji-resource';
export { GuildMemberResource } from './guild-member-resource';
export { GuildResource } from './guild-resource';
export { GuildRoleResource } from './guild-role-resource';
export { GuildStickerResource } from './guild-sticker-resource';
export { UserResource } from './user-resource';
export { VoiceResource } from './voice-resource';

View File

@ -0,0 +1,46 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordUser } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class UserResource extends BaseResource {
namespace: 'user' = 'user';
adapter: CacheAdapter;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
}
/**
* @inheritDoc
*/
async get(id: string): Promise<DiscordUser | null> {
const kv = await this.adapter.get(this.hashId(id));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(id: string, data: any, expire?: number): Promise<void> {
await this.adapter.set(this.hashId(id), data, expire);
}
/**
* @inheritDoc
*/
async remove(id: string): Promise<void> {
await this.adapter.remove(this.hashId(id));
}
}

View File

@ -0,0 +1,57 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordVoiceState } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class VoiceResource extends BaseResource {
namespace: 'voice' = 'voice';
adapter: CacheAdapter;
constructor(adapter: CacheAdapter) {
super();
this.adapter = adapter;
}
/**
* @inheritDoc
*/
async get(id: string, guild: string): Promise<DiscordVoiceState | null> {
const kv = await this.adapter.get(this.hashGuildId(id, guild));
if (kv) {
return kv;
}
return null;
}
/**
* @inheritDoc
*/
async set(
id: string,
guild: string,
data: any,
expire?: number
): Promise<void> {
if (!data.guild_id) {
data.guild_id = guild;
}
delete data.member;
await this.adapter.set(this.hashGuildId(id, guild), data, expire);
}
/**
* @inheritDoc
*/
async remove(id: string, guild: string): Promise<void> {
await this.adapter.remove(this.hashGuildId(id, guild));
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@biscuitland/core",
"version": "1.3.0",
"version": "1.3.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
@ -23,9 +23,9 @@
}
},
"dependencies": {
"@biscuitland/api-types": "^1.2.0",
"@biscuitland/rest": "^1.2.0",
"@biscuitland/ws": "^1.2.0"
"@biscuitland/api-types": "^1.3.1",
"@biscuitland/rest": "^1.3.1",
"@biscuitland/ws": "^1.3.1"
},
"devDependencies": {
"tsup": "^6.1.3"

View File

@ -1,6 +1,6 @@
{
"name": "@biscuitland/helpers",
"version": "1.3.0",
"version": "1.3.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
@ -23,8 +23,8 @@
}
},
"dependencies": {
"@biscuitland/api-types": "^1.2.0",
"@biscuitland/core": "^1.2.0"
"@biscuitland/api-types": "^1.3.1",
"@biscuitland/core": "^1.3.1"
},
"devDependencies": {
"tsup": "^6.1.3"

View File

@ -1,6 +1,6 @@
{
"name": "@biscuitland/rest",
"version": "1.3.0",
"version": "1.3.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
@ -23,7 +23,7 @@
}
},
"dependencies": {
"@biscuitland/api-types": "^1.2.0"
"@biscuitland/api-types": "^1.3.1"
},
"devDependencies": {
"tsup": "^6.1.3"

View File

@ -1,6 +1,6 @@
{
"name": "@biscuitland/ws",
"version": "1.3.0",
"version": "1.3.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
@ -23,7 +23,7 @@
}
},
"dependencies": {
"@biscuitland/api-types": "^1.2.0",
"@biscuitland/api-types": "^1.3.1",
"ws": "^8.8.1"
},
"devDependencies": {