diff --git a/package.json b/package.json index fec2f64..f0a988b 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,12 @@ }, "devDependencies": { "@biomejs/biome": "^1.9.4", - "nano-staged": "^0.8.0" + "nano-staged": "^0.8.0", + "rimraf": "^6.0.1" }, "nano-staged": { - "*.{js,ts,cjs,mjs,json}": ["biome check --write --"] + "*.{js,ts,cjs,mjs,json}": [ + "biome check --write --" + ] } } diff --git a/packages/client/src/actor/actor.ts b/packages/client/src/actor/actor.ts index 5d41e11..22a4d0d 100644 --- a/packages/client/src/actor/actor.ts +++ b/packages/client/src/actor/actor.ts @@ -1,6 +1,10 @@ import type { AppBskyActorDefs, AppBskyFeedGetAuthorFeed, + AppBskyGraphDefs, + At, + ComAtprotoLabelDefs, + ComAtprotoRepoStrongRef, } from '@tsky/lexicons'; import type { Client } from '~/agent/client'; import type { RPCOptions } from '~/types'; @@ -8,22 +12,11 @@ import { Paginator } from '~/utils'; export class Actor { client: Client; - identifier: string; + did: At.DID; - constructor(client: Client, identifier: string) { + constructor(client: Client, did: At.DID) { this.client = client; - this.identifier = identifier; - } - - /** - * Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth. - */ - async profile(): Promise { - const res = await this.client.get('app.bsky.actor.getProfile', { - params: { actor: this.identifier }, - }); - - return res.data; + this.did = did; } /** @@ -32,7 +25,7 @@ export class Actor { starterPacks(limit?: number, options: RPCOptions = {}) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.graph.getActorStarterPacks', { - params: { cursor, actor: this.identifier, limit }, + params: { cursor, actor: this.did, limit }, ...options, }); @@ -48,13 +41,19 @@ export class Actor { const res = await this.client.get('app.bsky.graph.getFollowers', { params: { cursor, - actor: this.identifier, + actor: this.did, limit, }, ...options, }); - return res.data; + return { + ...res.data, + subject: new ActorProfile(this.client, res.data.subject), + followers: res.data.followers.map( + (follower) => new ActorProfile(this.client, follower), + ), + }; }); } @@ -66,13 +65,19 @@ export class Actor { const res = await this.client.get('app.bsky.graph.getFollows', { params: { cursor, - actor: this.identifier, + actor: this.did, limit, }, ...options, }); - return res.data; + return { + ...res.data, + subject: new ActorProfile(this.client, res.data.subject), + follows: res.data.follows.map( + (follow) => new ActorProfile(this.client, follow), + ), + }; }); } @@ -84,13 +89,17 @@ export class Actor { const res = await this.client.get('app.bsky.graph.getLists', { params: { cursor, - actor: this.identifier, + actor: this.did, limit, }, ...options, }); - return res.data; + return { + ...res.data, + // TODO: Solve this + // lists: res.data.lists.map((list) => new List(this.client, list)), + }; }); } @@ -100,13 +109,18 @@ export class Actor { async relationships(others?: string[], options?: RPCOptions) { const res = await this.client.get('app.bsky.graph.getRelationships', { params: { - actor: this.identifier, + actor: this.did, others, }, ...options, }); - return res.data; + return { + ...res.data, + actor: res.data.actor + ? new Actor(this.client, res.data.actor) + : undefined, + }; } /** @@ -115,7 +129,7 @@ export class Actor { feeds(limit?: number, options?: RPCOptions) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.feed.getActorFeeds', { - params: { cursor, actor: this.identifier, limit }, + params: { cursor, actor: this.did, limit }, ...options, }); @@ -132,7 +146,7 @@ export class Actor { ) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.feed.getAuthorFeed', { - params: { cursor, ...params, actor: this.identifier }, + params: { cursor, ...params, actor: this.did }, ...options, }); @@ -140,3 +154,76 @@ export class Actor { }); } } + +// TODO: we can give this a better name +export class ActorWithProfileFunction extends Actor { + async profile() { + const data = await this.client + .get('app.bsky.actor.getProfile', { + params: { actor: this.did }, + }) + .then((res) => res.data); + + if ( + data.viewer?.knownFollowers?.followers && + data.viewer?.knownFollowers?.followers.length > 0 + ) { + data.viewer.knownFollowers.followers = + data.viewer.knownFollowers.followers.map( + (follower) => new BasicActorProfile(this.client, follower), + ); + } + + return data; + } +} + +export class BasicActorProfile + extends Actor + implements AppBskyActorDefs.ProfileViewBasic +{ + // @ts-expect-error - We added this property with Object.assign + handle: string; + associated?: AppBskyActorDefs.ProfileAssociated; + avatar?: string; + createdAt?: string; + displayName?: string; + labels?: ComAtprotoLabelDefs.Label[]; + viewer?: AppBskyActorDefs.ViewerState; + $type?: string; + + constructor(client: Client, actor: AppBskyActorDefs.ProfileViewBasic) { + super(client, actor.did); + Object.assign(this, actor); + } +} + +export class ActorProfile + extends BasicActorProfile + implements AppBskyActorDefs.ProfileView +{ + description?: string; + indexedAt?: string; + + constructor(client: Client, actor: AppBskyActorDefs.ProfileViewDetailed) { + super(client, actor); + Object.assign(this, actor); + } +} + +export class DetailedActorProfile + extends ActorProfile + implements AppBskyActorDefs.ProfileViewDetailed +{ + banner?: string; + followersCount?: number; + followsCount?: number; + joinedViaStarterPack?: AppBskyGraphDefs.StarterPackViewBasic; + pinnedPost?: ComAtprotoRepoStrongRef.Main; + postsCount?: number; + + constructor(client: Client, actor: AppBskyActorDefs.ProfileViewDetailed) { + super(client, actor); + Object.assign(this, actor); + } +} diff --git a/packages/client/src/agent/agent.ts b/packages/client/src/agent/agent.ts index f1e3c00..31e7bb1 100644 --- a/packages/client/src/agent/agent.ts +++ b/packages/client/src/agent/agent.ts @@ -1,28 +1,36 @@ import { type CredentialManager, XRPC } from '@atcute/client'; -import type { Queries } from '@tsky/lexicons'; -import { Actor } from '~/actor'; +import type { + AppBskyGraphGetStarterPack, + AppBskyGraphGetStarterPacks, + At, +} from '@tsky/lexicons'; +import { ActorWithProfileFunction } from '~/actor'; import { Feed } from '~/feed'; import { List } from '~/list'; -import { StarterPack } from '~/starterpack'; +import { Search } from '~/search'; +import type { RPCOptions } from '~/types'; import { User } from '~/user'; import { Video } from '~/video'; import { Client } from './client'; export class Agent { - private client: Client; + client: Client; constructor(private handler: CredentialManager) { // Initialize the client const xrpc = new XRPC({ handler: this.handler }); - this.client = new Client(xrpc); + this.client = new Client(xrpc, this.handler); } get session() { return this.handler.session; } - actor(identifier: string) { - return new Actor(this.client, identifier); + /** + * Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth. + */ + async actor(identifier: At.DID): Promise { + return new ActorWithProfileFunction(this.client, identifier); } list(uri: string) { @@ -33,12 +41,16 @@ export class Agent { return new Feed(this.client); } + get search() { + return new Search(this.client); + } + get user() { if (!this.session) { throw new Error('There is no active session'); } - return new User(this.client, this.session.handle); + return new User(this.client, this.session.did); } get video() { @@ -49,7 +61,38 @@ export class Agent { return new Video(this.client); } - get starterpack() { - return new StarterPack(this.client); + /** + * Gets a view of a starter pack. + */ + startpacks( + uri: string, + options?: RPCOptions, + ): Promise; + /** + * Get views for a list of starter packs. + */ + startpacks( + uris: string[], + options?: RPCOptions, + ): Promise; + + async startpacks(uris: string | string[], options: RPCOptions = {}) { + if (Array.isArray(uris)) { + const res = await this.client.get('app.bsky.graph.getStarterPacks', { + params: { + uris, + }, + ...options, + }); + + return res.data.starterPacks; + } + + const res = await this.client.get('app.bsky.graph.getStarterPack', { + params: { starterPack: uris }, + ...options, + }); + + return res.data; } } diff --git a/packages/client/src/agent/client.ts b/packages/client/src/agent/client.ts index 34a017c..81b59ad 100644 --- a/packages/client/src/agent/client.ts +++ b/packages/client/src/agent/client.ts @@ -1,24 +1,31 @@ import type { + CredentialManager, RPCOptions, XRPC, XRPCRequestOptions, XRPCResponse, } from '@atcute/client'; -import type { Procedures, Queries } from '@tsky/lexicons'; +import type { At, Procedures, Queries } from '@tsky/lexicons'; +import { parseAtUri } from '~/utils'; +import type { RPCOptions as GenericReqOptions } from '../types'; // From @atcute/client type OutputOf = T extends { - // biome-ignore lint/suspicious/noExplicitAny: - output: any; + output: unknown; } ? T['output'] : never; -export class Client { +const NO_SESSION_ERROR = + 'No session found. Please login to perform this action.'; + +export class Client { xrpc: XRPC; + crenditials: CredentialManager; - constructor(xrpc: XRPC) { + constructor(xrpc: XRPC, crenditials: CredentialManager) { this.xrpc = xrpc; + this.crenditials = crenditials; } /** @@ -27,10 +34,10 @@ export class Client { * @param options Options to include like parameters * @returns The response of the request */ - async get( + async get( nsid: K, - options: RPCOptions, - ): Promise>> { + options: RPCOptions, + ): Promise>> { // biome-ignore lint/suspicious/noExplicitAny: return this.xrpc.get(nsid as any, options); } @@ -41,10 +48,10 @@ export class Client { * @param options Options to include like input body or parameters * @returns The response of the request */ - async call( + async call( nsid: K, - options: RPCOptions, - ): Promise>> { + options: RPCOptions, + ): Promise>> { // biome-ignore lint/suspicious/noExplicitAny: return this.xrpc.call(nsid as any, options); } @@ -53,4 +60,82 @@ export class Client { async request(options: XRPCRequestOptions): Promise { return this.xrpc.request(options); } + + /** + * Create a record. + * @param nsid The collection's NSID. + * @param record The record to create. + * @param rkey The rkey to use. + * @returns The record's AT URI and CID. + */ + async createRecord( + nsid: K, + record: Omit, '$type' | 'createdAt'>, + rkey?: string, + ): Promise> { + if (!this.crenditials.session) { + throw new Error(NO_SESSION_ERROR); + } + const response = await this.call('com.atproto.repo.createRecord', { + data: { + collection: nsid, + record: { + $type: nsid, + createdAt: new Date().toISOString(), + ...record, + }, + repo: this.crenditials.session.did, + ...(rkey ? { rkey } : {}), + }, + }); + return response.data; + } + + /** + * Put a record in place of an existing record. + * @param nsid The collection's NSID. + * @param record The record to put. + * @param rkey The rkey to use. + * @returns The record's AT URI and CID. + */ + async putRecord( + nsid: string, + record: object, + rkey: string, + ): Promise> { + if (!this.crenditials.session) { + throw new Error(NO_SESSION_ERROR); + } + const response = await this.call('com.atproto.repo.putRecord', { + data: { + collection: nsid, + record: { + $type: nsid, + createdAt: new Date().toISOString(), + ...record, + }, + repo: this.crenditials.session.did, + rkey, + }, + }); + return response.data; + } + + /** + * Delete a record. + * @param uri The record's AT URI. + */ + async deleteRecord( + uri: At.Uri, + options: GenericReqOptions = {}, + ): Promise { + const { host: repo, collection, rkey } = parseAtUri(uri); + if (repo !== this.crenditials.session?.did) { + throw new Error('Can only delete own record.'); + } + await this.call('com.atproto.repo.deleteRecord', { + data: { collection, repo, rkey }, + ...options, + }); + } } diff --git a/packages/client/src/list/list.ts b/packages/client/src/list/list.ts index e036d6c..062fd1f 100644 --- a/packages/client/src/list/list.ts +++ b/packages/client/src/list/list.ts @@ -1,3 +1,4 @@ +import { ActorProfile } from '~/actor'; import type { Client } from '~/agent/client'; import type { RPCOptions } from '~/types'; import { Paginator } from '~/utils'; @@ -22,7 +23,13 @@ export class List { ...options, }); - return res.data; + return { + ...res.data, + items: res.data.items.map((item) => ({ + ...item, + subject: new ActorProfile(this.client, item.subject), + })), + }; }); } diff --git a/packages/client/src/post/post.ts b/packages/client/src/post/post.ts index 5db0b25..7a7b598 100644 --- a/packages/client/src/post/post.ts +++ b/packages/client/src/post/post.ts @@ -1,26 +1,74 @@ import type { + AppBskyEmbedExternal, + AppBskyEmbedImages, + AppBskyEmbedRecord, + AppBskyEmbedRecordWithMedia, + AppBskyEmbedVideo, + AppBskyFeedDefs, AppBskyFeedGetLikes, AppBskyFeedGetPostThread, AppBskyFeedGetQuotes, AppBskyFeedGetRepostedBy, - AppBskyFeedSearchPosts, + ComAtprotoLabelDefs, + Typed, } from '@tsky/lexicons'; +import { BasicActorProfile } from '~/actor'; import type { Client } from '~/agent/client'; import type { RPCOptions } from '~/types'; -import { Paginator } from '~/utils'; +import { Paginator, parseAtUri } from '~/utils'; -export class Post { - constructor(private client: Client) {} +export class Post implements AppBskyFeedDefs.PostView { + uri: string; + author: BasicActorProfile; + cid: string; + indexedAt: string; + record: unknown; + embed?: + | Typed + | Typed + | Typed + | Typed + | Typed; + labels?: ComAtprotoLabelDefs.Label[]; + likeCount?: number; + quoteCount?: number; + replyCount?: number; + repostCount?: number; + threadgate?: AppBskyFeedDefs.ThreadgateView; + viewer?: AppBskyFeedDefs.ViewerState; + $type?: string; + + constructor( + private client: Client, + payload: AppBskyFeedDefs.PostView, + ) { + Object.assign(this, payload); + this.author = new BasicActorProfile(this.client, payload.author); + this.cid = ''; // TODO: temporary type fix + this.uri = ''; // TODO: temporary type fix + this.indexedAt = ''; // TODO: temporary type fix + } + + isOfCurrentUser() { + const { host: repo } = parseAtUri(this.uri); + return repo !== this.client.crenditials.session?.did; + } + + remove(options: RPCOptions = {}) { + this.client.deleteRecord(this.uri, options); + } + + // TODO: method for liking, unliking, reposting, un-reposting, quoting, etc. /** * Get posts in a thread. Does not require auth, but additional metadata and filtering will be applied for authed requests. */ async threads( - params: AppBskyFeedGetPostThread.Params, + params: Omit = {}, options: RPCOptions = {}, ) { const res = await this.client.get('app.bsky.feed.getPostThread', { - params, + params: { uri: this.uri, ...params }, ...options, }); @@ -30,10 +78,13 @@ export class Post { /** * Get like records which reference a subject (by AT-URI and CID). */ - likes(params: AppBskyFeedGetLikes.Params, options: RPCOptions = {}) { + likes( + params: Omit = {}, + options: RPCOptions = {}, + ) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.feed.getLikes', { - params: { cursor, ...params }, + params: { cursor, uri: this.uri, ...params }, ...options, }); @@ -44,10 +95,13 @@ export class Post { /** * Get a list of quotes for a given post. */ - quotes(params: AppBskyFeedGetQuotes.Params, options: RPCOptions = {}) { + quotes( + params: Omit = {}, + options: RPCOptions = {}, + ) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.feed.getQuotes', { - params: { cursor, ...params }, + params: { cursor, uri: this.uri, ...params }, ...options, }); @@ -59,30 +113,12 @@ export class Post { * Get a list of reposts for a given post. */ repostedBy( - params: AppBskyFeedGetRepostedBy.Params, + params: Omit = {}, options: RPCOptions = {}, ) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.feed.getRepostedBy', { - params: { cursor, ...params }, - ...options, - }); - - return res.data; - }); - } - - /** - * Find posts matching search criteria, returning views of those posts. - */ - static search( - client: Client, - params: AppBskyFeedSearchPosts.Params, - options: RPCOptions = {}, - ) { - return Paginator.init(async (cursor) => { - const res = await client.get('app.bsky.feed.searchPosts', { - params: { cursor, ...params }, + params: { cursor, uri: this.uri, ...params }, ...options, }); diff --git a/packages/client/src/search/index.ts b/packages/client/src/search/index.ts new file mode 100644 index 0000000..5a2bdeb --- /dev/null +++ b/packages/client/src/search/index.ts @@ -0,0 +1 @@ +export * from './search'; diff --git a/packages/client/src/search/search.ts b/packages/client/src/search/search.ts new file mode 100644 index 0000000..a3c1b65 --- /dev/null +++ b/packages/client/src/search/search.ts @@ -0,0 +1,55 @@ +import type { + AppBskyFeedSearchPosts, + AppBskyGraphSearchStarterPacks, +} from '@tsky/lexicons'; +import type { Client } from '~/agent/client'; +import { Post } from '~/post'; +import { BasicStarterPack } from '~/starterpack'; +import type { RPCOptions } from '~/types'; +import { Paginator } from '~/utils'; + +export class Search { + constructor(private client: Client) {} + + /** + * Find posts matching search criteria, returning views of those posts. + */ + posts(params: AppBskyFeedSearchPosts.Params, options: RPCOptions = {}) { + return Paginator.init(async (cursor) => { + const res = await this.client.get('app.bsky.feed.searchPosts', { + params: { cursor, ...params }, + ...options, + }); + + return { + ...res.data, + posts: res.data.posts.map((post) => new Post(this.client, post)), + }; + }); + } + + /** + * Search for starter packs. + */ + starterpacks( + params: AppBskyGraphSearchStarterPacks.Params, + options?: RPCOptions, + ) { + return Paginator.init(async (cursor) => { + const res = await this.client.get('app.bsky.graph.searchStarterPacks', { + params: { + cursor, + ...params, + }, + ...options, + }); + + return { + ...res.data, + starterPacks: res.data.starterPacks.map( + (starterPack) => new BasicStarterPack(this.client, starterPack), + ), + }; + }); + } +} diff --git a/packages/client/src/starterpack/starterpack.ts b/packages/client/src/starterpack/starterpack.ts index 8b35a0b..98e4ca4 100644 --- a/packages/client/src/starterpack/starterpack.ts +++ b/packages/client/src/starterpack/starterpack.ts @@ -1,64 +1,47 @@ import type { - AppBskyGraphGetStarterPack, - AppBskyGraphGetStarterPacks, + AppBskyActorDefs, + AppBskyFeedDefs, + AppBskyGraphDefs, + ComAtprotoLabelDefs, } from '@tsky/lexicons'; +import { BasicActorProfile } from '~/actor'; import type { Client } from '~/agent/client'; -import type { RPCOptions } from '~/types'; -import { Paginator } from '~/utils'; -export class StarterPack { - constructor(private client: Client) {} - - /** - * Gets a view of a starter pack. - */ - view( - uri: string, - options: RPCOptions, - ): Promise; - /** - * Get views for a list of starter packs. - */ - view( - uris: string[], - options: RPCOptions, - ): Promise; - - async view(uris: string | string[], options: RPCOptions) { - if (Array.isArray(uris)) { - const res = await this.client.get('app.bsky.graph.getStarterPacks', { - params: { - uris, - }, - ...options, - }); - - return res.data.starterPacks; - } - - const res = await this.client.get('app.bsky.graph.getStarterPack', { - params: { starterPack: uris }, - ...options, - }); - - return res.data; +class Starterpack { + cid: string; + creator: AppBskyActorDefs.ProfileViewBasic; + indexedAt: string; + record: unknown; + uri: string; + joinedAllTimeCount?: number | undefined; + joinedWeekCount?: number | undefined; + labels?: ComAtprotoLabelDefs.Label[] | undefined; + $type?: string | undefined; + + constructor( + private client: Client, + payload: AppBskyGraphDefs.StarterPackView, + ) { + Object.assign(this, payload); + this.creator = new BasicActorProfile(this.client, payload.creator); + this.cid = ''; // TODO: temporary type fix + this.uri = ''; // TODO: temporary type fix + this.indexedAt = ''; // TODO: temporary type fix } +} - /** - * Search for starter packs. - */ - search(query: string, limit?: number, options?: RPCOptions) { - return Paginator.init(async (cursor) => { - const res = await this.client.get('app.bsky.graph.searchStarterPacks', { - params: { - cursor, - q: query, - limit, - }, - ...options, - }); +export class BasicStarterPack + extends Starterpack + implements AppBskyGraphDefs.StarterPackViewBasic +{ + listItemCount?: number | undefined; +} - return res.data; - }); - } +export class StarterPack + extends Starterpack + implements AppBskyGraphDefs.StarterPackView +{ + feeds?: AppBskyFeedDefs.GeneratorView[]; + list?: AppBskyGraphDefs.ListViewBasic; + listItemsSample?: AppBskyGraphDefs.ListItemView[]; } diff --git a/packages/client/src/tsky/tsky.ts b/packages/client/src/tsky/tsky.ts index cebabfc..60a6ba9 100644 --- a/packages/client/src/tsky/tsky.ts +++ b/packages/client/src/tsky/tsky.ts @@ -6,17 +6,19 @@ import { Agent } from '~/agent'; import type { CreateAgentOptions } from './types'; export async function createAgent( - credentials: CreateAgentOptions, + credentials?: CreateAgentOptions, options?: CredentialManagerOptions, ) { const manager = new CredentialManager( options ?? { service: 'https://bsky.social' }, ); - if ('session' in credentials) { - await manager.resume(credentials.session); - } else { - await manager.login(credentials); + if (credentials) { + if ('session' in credentials) { + await manager.resume(credentials.session); + } else { + await manager.login(credentials); + } } return new Agent(manager); diff --git a/packages/client/src/user/index.ts b/packages/client/src/user/index.ts index 99e5101..c47a4c0 100644 --- a/packages/client/src/user/index.ts +++ b/packages/client/src/user/index.ts @@ -1,5 +1,5 @@ import type { AppBskyFeedGetTimeline } from '@tsky/lexicons'; -import { Actor } from '~/actor'; +import { ActorWithProfileFunction } from '~/actor'; import type { RPCOptions } from '~/types'; import { Paginator } from '~/utils'; import { Mute } from './mute'; @@ -8,7 +8,7 @@ import { Preferences } from './preferences'; import { Suggestion } from './suggestion'; import { Unmute } from './unmute'; -export class User extends Actor { +export class User extends ActorWithProfileFunction { get preferences() { return new Preferences(this.client); } @@ -39,7 +39,7 @@ export class User extends Actor { likes(limit?: number, options: RPCOptions = {}) { return Paginator.init(async (cursor) => { const res = await this.client.get('app.bsky.feed.getActorLikes', { - params: { cursor, actor: this.identifier, limit }, + params: { cursor, actor: this.did, limit }, ...options, }); diff --git a/packages/client/src/utils/index.ts b/packages/client/src/utils/index.ts index 544dc7f..98b9548 100644 --- a/packages/client/src/utils/index.ts +++ b/packages/client/src/utils/index.ts @@ -1 +1,2 @@ export * from './paginator'; +export * from './parse'; diff --git a/packages/client/src/utils/parse.ts b/packages/client/src/utils/parse.ts new file mode 100644 index 0000000..dc49221 --- /dev/null +++ b/packages/client/src/utils/parse.ts @@ -0,0 +1,15 @@ +const ATP_URI_REGEX = + // proto- --did-------------- --name---------------- --path---- --query-- --hash-- + /^(at:\/\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z0-9][a-z0-9.:-]*))(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i; + +export function parseAtUri(uri: string): { + host: string; + collection: string; + rkey: string; +} { + const match = uri.match(ATP_URI_REGEX); + if (!match) throw new Error(`Invalid AT URI: ${uri}`); + const [, _proto, host, pathname] = match; + const [collection = '', rkey = ''] = pathname.split('/').filter(Boolean); + return { host, collection, rkey }; +} diff --git a/packages/lex-cli/package.json b/packages/lex-cli/package.json index bfdac8c..dda3016 100644 --- a/packages/lex-cli/package.json +++ b/packages/lex-cli/package.json @@ -12,7 +12,7 @@ "bin": "./dist/index.js", "scripts": { "build": "tsc", - "clean": "rm -rf dist", + "clean": "rimraf dist", "prepare": "pnpm run clean && pnpm run build" }, "dependencies": { diff --git a/packages/lexicons/package.json b/packages/lexicons/package.json index 2e8adef..c7e382b 100644 --- a/packages/lexicons/package.json +++ b/packages/lexicons/package.json @@ -19,7 +19,7 @@ "scripts": { "build": "tsx ./scripts/generate-types.ts && tsc", "check-version-change": "tsx ./scripts/check-version-change.ts && tsc", - "clean": "rm -rf dist && rm -rf lexicons", + "clean": "rimraf dist && rimraf lexicons", "prepare": "pnpm run clean && pnpm run build" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 118bffc..ed9d517 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: nano-staged: specifier: ^0.8.0 version: 0.8.0 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 docs: devDependencies: @@ -2251,6 +2254,11 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + glob@11.0.1: + resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} + engines: {node: 20 || >=22} + hasBin: true + globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -2411,6 +2419,10 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.0.3: + resolution: {integrity: sha512-oSwM7q8PTHQWuZAlp995iPpPJ4Vkl7qT0ZRD+9duL9j2oBy6KcTfyxc8mEuHJYC+z/kbps80aJLkaNzTOrf/kw==} + engines: {node: 20 || >=22} + jose@5.9.6: resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} @@ -2460,6 +2472,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2557,6 +2573,10 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -2704,6 +2724,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} @@ -2929,6 +2953,11 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true + rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} + engines: {node: 20 || >=22} + hasBin: true + roarr@7.21.1: resolution: {integrity: sha512-3niqt5bXFY1InKU8HKWqqYTYjtrBaxBMnXELXCXUYgtNYGUtZM5rB46HIC430AyacL95iEniGf7RgqsesykLmQ==} engines: {node: '>=18.0'} @@ -6194,6 +6223,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@11.0.1: + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.3 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + globals@11.12.0: {} globals@15.12.0: {} @@ -6378,6 +6416,10 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.0.3: + dependencies: + '@isaacs/cliui': 8.0.2 + jose@5.9.6: {} js-tokens@4.0.0: {} @@ -6415,6 +6457,8 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.0.2: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -6512,6 +6556,10 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -6624,6 +6672,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.2 + minipass: 7.1.2 + path-to-regexp@0.1.12: {} pathe@2.0.3: {} @@ -6858,6 +6911,11 @@ snapshots: dependencies: glob: 10.4.5 + rimraf@6.0.1: + dependencies: + glob: 11.0.1 + package-json-from-dist: 1.0.1 + roarr@7.21.1: dependencies: fast-printf: 1.6.10