@sapphire/pieces 4.1.0 → 4.1.1-next.af3fb0d.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,62 +6,62 @@ All notable changes to this project will be documented in this file.
6
6
 
7
7
  ## 🚀 Features
8
8
 
9
- - Bun (#359) ([2f862f4](https://github.com/sapphiredev/pieces/commit/2f862f4d4d9a7c569118795db7d432fc3971a939))
9
+ - Bun (#359) ([2f862f4](https://github.com/sapphiredev/pieces/commit/2f862f4d4d9a7c569118795db7d432fc3971a939))
10
10
 
11
11
  # [4.0.2](https://github.com/sapphiredev/pieces/compare/v4.0.2...v4.0.2) - (2023-12-05)
12
12
 
13
13
  ## 🐛 Bug Fixes
14
14
 
15
- - Properly package all files in dist for npm ([2faab8a](https://github.com/sapphiredev/pieces/commit/2faab8af9c604a6062ab078a34e4aba8ac92cc80))
15
+ - Properly package all files in dist for npm ([2faab8a](https://github.com/sapphiredev/pieces/commit/2faab8af9c604a6062ab078a34e4aba8ac92cc80))
16
16
 
17
17
  # [4.0.1](https://github.com/sapphiredev/pieces/compare/v4.0.1...v4.0.1) - (2023-12-05)
18
18
 
19
19
  ## 🐛 Bug Fixes
20
20
 
21
- - Bump transitive dependencies ([1da0283](https://github.com/sapphiredev/pieces/commit/1da0283459b0be9b2fa4ef5773dfa5616a95aec6))
21
+ - Bump transitive dependencies ([1da0283](https://github.com/sapphiredev/pieces/commit/1da0283459b0be9b2fa4ef5773dfa5616a95aec6))
22
22
 
23
23
  # [4.0.0](https://github.com/sapphiredev/pieces/compare/v4.0.0...v4.0.0) - (2023-12-04)
24
24
 
25
25
  ## 🏠 Refactor
26
26
 
27
- - Move `walk` to `ILoaderStrategy` (#352) ([540ac88](https://github.com/sapphiredev/pieces/commit/540ac884632b8c72d17aa4b422dfeb372ce743ed))
27
+ - Move `walk` to `ILoaderStrategy` (#352) ([540ac88](https://github.com/sapphiredev/pieces/commit/540ac884632b8c72d17aa4b422dfeb372ce743ed))
28
28
 
29
29
  ## 🐛 Bug Fixes
30
30
 
31
- - Properly split CJS and ESM ([41e8cec](https://github.com/sapphiredev/pieces/commit/41e8cec3c3b9ce1f91009d932a2a59fe0b42a6ac))
32
- - 💥 **BREAKING CHANGE:** This ensures that Pieces will properly load the files
33
- from the appropiate folder and we properly bundle CJS and ESM.
34
- To use this version of @sapphire/pieces you have to use @sapphire/framework
35
- v5.x or higher, or update your own usage of @sapphire/pieces to also
36
- properly split ESM and CJS.
31
+ - Properly split CJS and ESM ([41e8cec](https://github.com/sapphiredev/pieces/commit/41e8cec3c3b9ce1f91009d932a2a59fe0b42a6ac))
32
+ - 💥 **BREAKING CHANGE:** This ensures that Pieces will properly load the files
33
+ from the appropiate folder and we properly bundle CJS and ESM.
34
+ To use this version of @sapphire/pieces you have to use @sapphire/framework
35
+ v5.x or higher, or update your own usage of @sapphire/pieces to also
36
+ properly split ESM and CJS.
37
37
 
38
38
  # [3.10.0](https://github.com/sapphiredev/pieces/compare/v3.10.0...v3.10.0) - (2023-11-16)
39
39
 
40
40
  ## 🏠 Refactor
41
41
 
42
- - Rename `Piece.Context` to `Piece.LoaderContext` (#351) ([f5bb225](https://github.com/sapphiredev/pieces/commit/f5bb22508850e1aead0b7fadc802ac13e462dca4))
42
+ - Rename `Piece.Context` to `Piece.LoaderContext` (#351) ([f5bb225](https://github.com/sapphiredev/pieces/commit/f5bb22508850e1aead0b7fadc802ac13e462dca4))
43
43
 
44
44
  ## 🚀 Features
45
45
 
46
- - Use `StoreName` for improved type experience (#350) ([3c722ef](https://github.com/sapphiredev/pieces/commit/3c722ef2d57bc292920491a990cd91dddefc37bd))
47
- - **StoreRegistry:** Add `StoreOf` and `PieceOf` (#349) ([7b0ae1d](https://github.com/sapphiredev/pieces/commit/7b0ae1dba0e51084d35c3801e8c25c6d1dc3a54f))
46
+ - Use `StoreName` for improved type experience (#350) ([3c722ef](https://github.com/sapphiredev/pieces/commit/3c722ef2d57bc292920491a990cd91dddefc37bd))
47
+ - **StoreRegistry:** Add `StoreOf` and `PieceOf` (#349) ([7b0ae1d](https://github.com/sapphiredev/pieces/commit/7b0ae1dba0e51084d35c3801e8c25c6d1dc3a54f))
48
48
 
49
49
  # [3.9.0](https://github.com/sapphiredev/pieces/compare/v3.9.0...v3.9.0) - (2023-11-15)
50
50
 
51
51
  ## 🚀 Features
52
52
 
53
- - Revert 12be6ba006d549ba2250546b4fb3c35a9e5d25f2 "add symbol support for piece names (#346)" ([9424c20](https://github.com/sapphiredev/pieces/commit/9424c2020ab4a37c4db97d382f90e1bb8890b19f))
53
+ - Revert 12be6ba006d549ba2250546b4fb3c35a9e5d25f2 "add symbol support for piece names (#346)" ([9424c20](https://github.com/sapphiredev/pieces/commit/9424c2020ab4a37c4db97d382f90e1bb8890b19f))
54
54
 
55
55
  # [3.8.0](https://github.com/sapphiredev/pieces/compare/v3.8.0...v3.8.0) - (2023-11-15)
56
56
 
57
57
  ## 🐛 Bug Fixes
58
58
 
59
- - **AliasStore:** Pass `StoreName` type parameter to `Store` (#347) ([9a3492c](https://github.com/sapphiredev/pieces/commit/9a3492c963311296b4eb82119ef926c89e277cca))
59
+ - **AliasStore:** Pass `StoreName` type parameter to `Store` (#347) ([9a3492c](https://github.com/sapphiredev/pieces/commit/9a3492c963311296b4eb82119ef926c89e277cca))
60
60
 
61
61
  ## 🚀 Features
62
62
 
63
- - Add symbol support for piece names (#346) ([12be6ba](https://github.com/sapphiredev/pieces/commit/12be6ba006d549ba2250546b4fb3c35a9e5d25f2))
64
- - **StoreRegistry:** Add queue and virtual file support (#344) ([b7c0839](https://github.com/sapphiredev/pieces/commit/b7c0839cd8d562d9762bf4f13af080eb52db99de))
63
+ - Add symbol support for piece names (#346) ([12be6ba](https://github.com/sapphiredev/pieces/commit/12be6ba006d549ba2250546b4fb3c35a9e5d25f2))
64
+ - **StoreRegistry:** Add queue and virtual file support (#344) ([b7c0839](https://github.com/sapphiredev/pieces/commit/b7c0839cd8d562d9762bf4f13af080eb52db99de))
65
65
 
66
66
  # [3.7.1](https://github.com/sapphiredev/pieces/compare/v3.7.1...v3.7.1) - (2023-11-13)
67
67
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/StoreRegistry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAA4B;AAC5B,SAAS,mBAA8B;AACvC,SAAS,mBAAmB;AAC5B,SAAS,sCAAmD;AAN5D;AA8BO,IAAM,iBAAN,MAAM,uBAAsB,WAAiD;AAAA,EAA7E;AAAA;AAIN;AAAA;AAAA;AAAA,uBAAS,kCAAmC,IAAI,WAA+E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/H,MAAa,OAAO;AACnB,UAAM,WAA+B,CAAC;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,eAAS,KAAK,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,aAAa,gBAAsB,YAAY,EAAE,MAAM;AAC7D,UAAM,OAAO,YAAY,aAAa;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,YAAM,aAAa,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IAC1C;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,SAA0B,OAAuB;AACvD,SAAK,IAAI,MAAM,MAA0B,KAAsC;AAG/E,UAAM,QAAQ,mBAAK,kCAAiC,IAAI,MAAM,IAAI;AAClE,QAAI,OAAO;AACV,YAAM,8BAA8B,EAAE,KAAK,GAAG,KAAK;AACnD,yBAAK,kCAAiC,OAAO,MAAM,IAAI;AAAA,IACxD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAA4B,OAAuB;AACzD,SAAK,OAAO,MAAM,IAAwB;AAC1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAa,UAA8C,OAAuD;AACjH,UAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;AAElC,QAAI,OAAO;AACV,YAAM,MAAM,UAAU,KAAK;AAAA,IAC5B,OAAO;AACN,UAAI,CAAC,QAAQ,MAAM,KAAK,GAAG;AAC1B,cAAM,IAAI,UAAU,aAAa,MAAM,IAAI,oBAAoB,OAAO,MAAM,KAAK,CAAC,EAAE;AAAA,MACrF;AAEA,yBAAK,kCAAiC,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,IAClH;AAAA,EACD;AACD;AA/IU;AAJ0E;AAA7E,IAAM,gBAAN","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport { isClass } from '@sapphire/utilities';\nimport { join } from 'path';\nimport { LoaderError } from '../errors/LoaderError';\nimport { resolvePath, type Path } from '../internal/Path';\nimport { getRootData } from '../internal/RootScan';\nimport { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constants';\nimport type { Piece } from './Piece';\nimport type { Store, StoreManuallyRegisteredPiece } from './Store';\n\n/**\n * A strict-typed store registry. This is available in {@link container}.\n * @since 2.1.0\n * @example\n * ```typescript\n * // Adding new stores\n *\n * // Register the store:\n * container.stores.register(new RouteStore());\n *\n * // Augment Sapphire to add the new store, in case of a JavaScript\n * // project, this can be moved to an `Augments.d.ts` (or any other name)\n * // file somewhere:\n * declare module '@sapphire/pieces' {\n * export interface StoreRegistryEntries {\n * routes: RouteStore;\n * }\n * }\n * ```\n */\nexport class StoreRegistry extends Collection<StoreRegistryKey, StoreRegistryValue> {\n\t/**\n\t * The queue of pieces to load.\n\t */\n\treadonly #pendingManuallyRegisteredPieces = new Collection<StoreRegistryKey, StoreManuallyRegisteredPiece<StoreRegistryKey>[]>();\n\n\t/**\n\t * Loads all the registered stores.\n\t * @since 2.1.0\n\t */\n\tpublic async load() {\n\t\tconst promises: Promise<unknown>[] = [];\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tpromises.push(store.loadAll());\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Registers all user directories from the process working directory, the default value is obtained by assuming\n\t * CommonJS (high accuracy) but with fallback for ECMAScript Modules (reads package.json's `main` entry, fallbacks\n\t * to `process.cwd()`).\n\t *\n\t * By default, if you have this folder structure:\n\t * ```\n\t * /home/me/my-bot\n\t * ├─ src\n\t * │ ├─ commands\n\t * │ ├─ events\n\t * │ └─ main.js\n\t * └─ package.json\n\t * ```\n\t *\n\t * And you run `node src/main.js`, the directories `/home/me/my-bot/src/commands` and `/home/me/my-bot/src/events` will\n\t * be registered for the commands and events stores respectively, since both directories are located in the same\n\t * directory as your main file.\n\t *\n\t * **Note**: this also registers directories for all other stores, even if they don't have a folder, this allows you\n\t * to create new pieces and hot-load them later anytime.\n\t * @since 2.1.0\n\t * @param rootDirectory The root directory to register pieces at.\n\t */\n\tpublic registerPath(rootDirectory: Path = getRootData().root) {\n\t\tconst root = resolvePath(rootDirectory);\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tstore.registerPath(join(root, store.name));\n\t\t}\n\t}\n\n\t/**\n\t * Registers a store.\n\t *\n\t * @remarks\n\t *\n\t * - This method will allow {@linkcode StoreRegistry} to manage the store, meaning:\n\t * - {@linkcode StoreRegistry.registerPath()} will call the store's\n\t * {@linkcode Store.registerPath() registerPath()} method on call.\n\t * - {@linkcode StoreRegistry.load()} will call the store's {@linkcode Store.load() load()} method on call.\n\t * - {@linkcode StoreRegistry.loadPiece()} will call the store's {@linkcode Store.loadPiece() loadPiece()} method\n\t * on call.\n\t * - This will also add all the manually registered pieces by {@linkcode StoreRegistry.loadPiece()} in the store.\n\t *\n\t * It is generally recommended to register a store as early as possible, before any of the aforementioned methods\n\t * are called, otherwise you will have to manually call the aforementioned methods for the store to work properly.\n\t *\n\t * If there were manually registered pieces for this store with {@linkcode StoreRegistry.loadPiece()}, this method\n\t * will add them to the store and delete the queue. Note, however, that this method will not call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method, and as such, the pieces will not be loaded until\n\t * {@linkcode Store.loadAll()} is called.\n\t *\n\t * @since 2.1.0\n\t * @param store The store to register.\n\t */\n\tpublic register<T extends Piece>(store: Store<T>): this {\n\t\tthis.set(store.name as StoreRegistryKey, store as unknown as StoreRegistryValue);\n\n\t\t// If there was a queue for this store, add it to the store and delete the queue:\n\t\tconst queue = this.#pendingManuallyRegisteredPieces.get(store.name);\n\t\tif (queue) {\n\t\t\tstore[ManuallyRegisteredPiecesSymbol].push(...queue);\n\t\t\tthis.#pendingManuallyRegisteredPieces.delete(store.name);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Deregisters a store.\n\t * @since 2.1.0\n\t * @param store The store to deregister.\n\t */\n\tpublic deregister<T extends Piece>(store: Store<T>): this {\n\t\tthis.delete(store.name as StoreRegistryKey);\n\t\treturn this;\n\t}\n\n\t/**\n\t * If the store was {@link StoreRegistry.register registered}, this method will call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method.\n\t *\n\t * If it was called, the entry will be loaded immediately without queueing.\n\t *\n\t * @remarks\n\t *\n\t * - Pieces loaded this way will have their {@linkcode Piece.Context.root root} and\n\t * {@linkcode Piece.Context.path path} set to {@linkcode VirtualPath}, and as such, cannot be reloaded.\n\t * - This method is useful in environments where file system access is limited or unavailable, such as when using\n\t * {@link https://en.wikipedia.org/wiki/Serverless_computing Serverless Computing}.\n\t * - This method will not throw an error if a store with the given name does not exist, it will simply be queued\n\t * until it's registered.\n\t * - This method will always throw a {@link TypeError} if `entry.piece` is not a class.\n\t * - If the store is registered, this method will always throw a {@linkcode LoaderError} if the piece does not\n\t * extend the registered {@linkcode Store.Constructor store's piece constructor}.\n\t * - This operation is atomic, if any of the above errors are thrown, the piece will not be loaded.\n\t *\n\t * @seealso {@linkcode Store.loadPiece()}\n\t * @since 3.8.0\n\t * @param entry The entry to load.\n\t * @example\n\t * ```typescript\n\t * import { container } from '@sapphire/pieces';\n\t *\n\t * class PingCommand extends Command {\n\t * // ...\n\t * }\n\t *\n\t * container.stores.loadPiece({\n\t * store: 'commands',\n\t * name: 'ping',\n\t * piece: PingCommand\n\t * });\n\t * ```\n\t */\n\tpublic async loadPiece<StoreName extends StoreRegistryKey>(entry: StoreManagerManuallyRegisteredPiece<StoreName>) {\n\t\tconst store = this.get(entry.store) as Store<Piece, StoreName> | undefined;\n\n\t\tif (store) {\n\t\t\tawait store.loadPiece(entry);\n\t\t} else {\n\t\t\tif (!isClass(entry.piece)) {\n\t\t\t\tthrow new TypeError(`The piece ${entry.name} is not a Class. ${String(entry.piece)}`);\n\t\t\t}\n\n\t\t\tthis.#pendingManuallyRegisteredPieces.ensure(entry.store, () => []).push({ name: entry.name, piece: entry.piece });\n\t\t}\n\t}\n}\n\nexport interface StoreRegistry {\n\tget<K extends StoreRegistryKey>(key: K): StoreRegistryEntries[K];\n\tget(key: string): undefined;\n\thas(key: StoreRegistryKey): true;\n\thas(key: string): false;\n}\n\n/**\n * A type utility to get the keys of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryKey = keyof StoreRegistryEntries;\n\n/**\n * A type utility to get the values of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryValue = StoreRegistryEntries[StoreRegistryKey];\n\n/**\n * The {@link StoreRegistry}'s registry, use module augmentation against this interface when adding new stores.\n * @since 2.1.0\n */\nexport interface StoreRegistryEntries {}\n\n/**\n * An entry for a manually registered piece using {@linkcode StoreRegistry.loadPiece()}.\n * @seealso {@linkcode StoreRegistry.loadPiece()}\n * @since 3.8.0\n */\nexport interface StoreManagerManuallyRegisteredPiece<StoreName extends StoreRegistryKey> extends StoreManuallyRegisteredPiece<StoreName> {\n\tstore: StoreName;\n}\n\n/**\n * Type utility to get the {@linkcode Store} given its name.\n * @since 3.10.0\n */\nexport type StoreOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Store<Piece<Piece.Options, StoreName>>\n\t: StoreRegistryEntries[StoreName];\n\n/**\n * Type utility to get the {@linkcode Piece} given its {@linkcode Store}'s name.\n * @since 3.10.0\n */\nexport type PieceOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Piece<Piece.Options, StoreName>\n\t: StoreRegistryEntries[StoreName] extends Store<infer PieceType>\n\t ? PieceType\n\t : Piece<Piece.Options, StoreName>;\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/StoreRegistry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAA4B;AAC5B,SAAS,mBAA8B;AACvC,SAAS,mBAAmB;AAC5B,SAAS,sCAAmD;AAN5D;AA8BO,IAAM,iBAAN,MAAM,uBAAsB,WAAiD;AAAA,EAA7E;AAAA;AAIN;AAAA;AAAA;AAAA,uBAAS,kCAAmC,IAAI,WAA+E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/H,MAAa,OAAO;AACnB,UAAM,WAA+B,CAAC;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,eAAS,KAAK,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,aAAa,gBAAsB,YAAY,EAAE,MAAM;AAC7D,UAAM,OAAO,YAAY,aAAa;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,YAAM,aAAa,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IAC1C;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,SAA0B,OAAuB;AACvD,SAAK,IAAI,MAAM,MAA0B,KAAsC;AAG/E,UAAM,QAAQ,mBAAK,kCAAiC,IAAI,MAAM,IAAI;AAClE,QAAI,OAAO;AACV,YAAM,8BAA8B,EAAE,KAAK,GAAG,KAAK;AACnD,yBAAK,kCAAiC,OAAO,MAAM,IAAI;AAAA,IACxD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAA4B,OAAuB;AACzD,SAAK,OAAO,MAAM,IAAwB;AAC1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAa,UAA8C,OAAuD;AACjH,UAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;AAElC,QAAI,OAAO;AACV,YAAM,MAAM,UAAU,KAAK;AAAA,IAC5B,OAAO;AACN,UAAI,CAAC,QAAQ,MAAM,KAAK,GAAG;AAC1B,cAAM,IAAI,UAAU,aAAa,MAAM,IAAI,oBAAoB,OAAO,MAAM,KAAK,CAAC,EAAE;AAAA,MACrF;AAEA,yBAAK,kCAAiC,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,IAClH;AAAA,EACD;AACD;AA/IU;AAJ0E;AAA7E,IAAM,gBAAN","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport { isClass } from '@sapphire/utilities';\nimport { join } from 'path';\nimport { LoaderError } from '../errors/LoaderError';\nimport { resolvePath, type Path } from '../internal/Path';\nimport { getRootData } from '../internal/RootScan';\nimport { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constants';\nimport type { Piece } from './Piece';\nimport type { Store, StoreManuallyRegisteredPiece } from './Store';\n\n/**\n * A strict-typed store registry. This is available in {@link container}.\n * @since 2.1.0\n * @example\n * ```typescript\n * // Adding new stores\n *\n * // Register the store:\n * container.stores.register(new RouteStore());\n *\n * // Augment Sapphire to add the new store, in case of a JavaScript\n * // project, this can be moved to an `Augments.d.ts` (or any other name)\n * // file somewhere:\n * declare module '@sapphire/pieces' {\n * export interface StoreRegistryEntries {\n * routes: RouteStore;\n * }\n * }\n * ```\n */\nexport class StoreRegistry extends Collection<StoreRegistryKey, StoreRegistryValue> {\n\t/**\n\t * The queue of pieces to load.\n\t */\n\treadonly #pendingManuallyRegisteredPieces = new Collection<StoreRegistryKey, StoreManuallyRegisteredPiece<StoreRegistryKey>[]>();\n\n\t/**\n\t * Loads all the registered stores.\n\t * @since 2.1.0\n\t */\n\tpublic async load() {\n\t\tconst promises: Promise<unknown>[] = [];\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tpromises.push(store.loadAll());\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Registers all user directories from the process working directory, the default value is obtained by assuming\n\t * CommonJS (high accuracy) but with fallback for ECMAScript Modules (reads package.json's `main` entry, fallbacks\n\t * to `process.cwd()`).\n\t *\n\t * By default, if you have this folder structure:\n\t * ```\n\t * /home/me/my-bot\n\t * ├─ src\n\t * │ ├─ commands\n\t * │ ├─ events\n\t * │ └─ main.js\n\t * └─ package.json\n\t * ```\n\t *\n\t * And you run `node src/main.js`, the directories `/home/me/my-bot/src/commands` and `/home/me/my-bot/src/events` will\n\t * be registered for the commands and events stores respectively, since both directories are located in the same\n\t * directory as your main file.\n\t *\n\t * **Note**: this also registers directories for all other stores, even if they don't have a folder, this allows you\n\t * to create new pieces and hot-load them later anytime.\n\t * @since 2.1.0\n\t * @param rootDirectory The root directory to register pieces at.\n\t */\n\tpublic registerPath(rootDirectory: Path = getRootData().root) {\n\t\tconst root = resolvePath(rootDirectory);\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tstore.registerPath(join(root, store.name));\n\t\t}\n\t}\n\n\t/**\n\t * Registers a store.\n\t *\n\t * @remarks\n\t *\n\t * - This method will allow {@linkcode StoreRegistry} to manage the store, meaning:\n\t * - {@linkcode StoreRegistry.registerPath()} will call the store's\n\t * {@linkcode Store.registerPath() registerPath()} method on call.\n\t * - {@linkcode StoreRegistry.load()} will call the store's {@linkcode Store.load() load()} method on call.\n\t * - {@linkcode StoreRegistry.loadPiece()} will call the store's {@linkcode Store.loadPiece() loadPiece()} method\n\t * on call.\n\t * - This will also add all the manually registered pieces by {@linkcode StoreRegistry.loadPiece()} in the store.\n\t *\n\t * It is generally recommended to register a store as early as possible, before any of the aforementioned methods\n\t * are called, otherwise you will have to manually call the aforementioned methods for the store to work properly.\n\t *\n\t * If there were manually registered pieces for this store with {@linkcode StoreRegistry.loadPiece()}, this method\n\t * will add them to the store and delete the queue. Note, however, that this method will not call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method, and as such, the pieces will not be loaded until\n\t * {@linkcode Store.loadAll()} is called.\n\t *\n\t * @since 2.1.0\n\t * @param store The store to register.\n\t */\n\tpublic register<T extends Piece>(store: Store<T>): this {\n\t\tthis.set(store.name as StoreRegistryKey, store as unknown as StoreRegistryValue);\n\n\t\t// If there was a queue for this store, add it to the store and delete the queue:\n\t\tconst queue = this.#pendingManuallyRegisteredPieces.get(store.name);\n\t\tif (queue) {\n\t\t\tstore[ManuallyRegisteredPiecesSymbol].push(...queue);\n\t\t\tthis.#pendingManuallyRegisteredPieces.delete(store.name);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Deregisters a store.\n\t * @since 2.1.0\n\t * @param store The store to deregister.\n\t */\n\tpublic deregister<T extends Piece>(store: Store<T>): this {\n\t\tthis.delete(store.name as StoreRegistryKey);\n\t\treturn this;\n\t}\n\n\t/**\n\t * If the store was {@link StoreRegistry.register registered}, this method will call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method.\n\t *\n\t * If it was called, the entry will be loaded immediately without queueing.\n\t *\n\t * @remarks\n\t *\n\t * - Pieces loaded this way will have their {@linkcode Piece.Context.root root} and\n\t * {@linkcode Piece.Context.path path} set to {@linkcode VirtualPath}, and as such, cannot be reloaded.\n\t * - This method is useful in environments where file system access is limited or unavailable, such as when using\n\t * {@link https://en.wikipedia.org/wiki/Serverless_computing Serverless Computing}.\n\t * - This method will not throw an error if a store with the given name does not exist, it will simply be queued\n\t * until it's registered.\n\t * - This method will always throw a {@link TypeError} if `entry.piece` is not a class.\n\t * - If the store is registered, this method will always throw a {@linkcode LoaderError} if the piece does not\n\t * extend the registered {@linkcode Store.Constructor store's piece constructor}.\n\t * - This operation is atomic, if any of the above errors are thrown, the piece will not be loaded.\n\t *\n\t * @seealso {@linkcode Store.loadPiece()}\n\t * @since 3.8.0\n\t * @param entry The entry to load.\n\t * @example\n\t * ```typescript\n\t * import { container } from '@sapphire/pieces';\n\t *\n\t * class PingCommand extends Command {\n\t * // ...\n\t * }\n\t *\n\t * container.stores.loadPiece({\n\t * store: 'commands',\n\t * name: 'ping',\n\t * piece: PingCommand\n\t * });\n\t * ```\n\t */\n\tpublic async loadPiece<StoreName extends StoreRegistryKey>(entry: StoreManagerManuallyRegisteredPiece<StoreName>) {\n\t\tconst store = this.get(entry.store) as Store<Piece, StoreName> | undefined;\n\n\t\tif (store) {\n\t\t\tawait store.loadPiece(entry);\n\t\t} else {\n\t\t\tif (!isClass(entry.piece)) {\n\t\t\t\tthrow new TypeError(`The piece ${entry.name} is not a Class. ${String(entry.piece)}`);\n\t\t\t}\n\n\t\t\tthis.#pendingManuallyRegisteredPieces.ensure(entry.store, () => []).push({ name: entry.name, piece: entry.piece });\n\t\t}\n\t}\n}\n\nexport interface StoreRegistry {\n\tget<K extends StoreRegistryKey>(key: K): StoreRegistryEntries[K];\n\tget(key: string): undefined;\n\thas(key: StoreRegistryKey): true;\n\thas(key: string): false;\n}\n\n/**\n * A type utility to get the keys of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryKey = keyof StoreRegistryEntries;\n\n/**\n * A type utility to get the values of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryValue = StoreRegistryEntries[StoreRegistryKey];\n\n/**\n * The {@link StoreRegistry}'s registry, use module augmentation against this interface when adding new stores.\n * @since 2.1.0\n */\nexport interface StoreRegistryEntries {}\n\n/**\n * An entry for a manually registered piece using {@linkcode StoreRegistry.loadPiece()}.\n * @seealso {@linkcode StoreRegistry.loadPiece()}\n * @since 3.8.0\n */\nexport interface StoreManagerManuallyRegisteredPiece<StoreName extends StoreRegistryKey> extends StoreManuallyRegisteredPiece<StoreName> {\n\tstore: StoreName;\n}\n\n/**\n * Type utility to get the {@linkcode Store} given its name.\n * @since 3.10.0\n */\nexport type StoreOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Store<Piece<Piece.Options, StoreName>>\n\t: StoreRegistryEntries[StoreName];\n\n/**\n * Type utility to get the {@linkcode Piece} given its {@linkcode Store}'s name.\n * @since 3.10.0\n */\nexport type PieceOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Piece<Piece.Options, StoreName>\n\t: StoreRegistryEntries[StoreName] extends Store<infer PieceType>\n\t\t? PieceType\n\t\t: Piece<Piece.Options, StoreName>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/StoreRegistry.ts"],"names":[],"mappings":";;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAA4B;AAC5B,SAAS,mBAA8B;AACvC,SAAS,mBAAmB;AAC5B,SAAS,sCAAmD;AAN5D;AA8BO,IAAM,iBAAN,MAAM,uBAAsB,WAAiD;AAAA,EAA7E;AAAA;AAIN;AAAA;AAAA;AAAA,uBAAS,kCAAmC,IAAI,WAA+E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/H,MAAa,OAAO;AACnB,UAAM,WAA+B,CAAC;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,eAAS,KAAK,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,aAAa,gBAAsB,YAAY,EAAE,MAAM;AAC7D,UAAM,OAAO,YAAY,aAAa;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,YAAM,aAAa,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IAC1C;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,SAA0B,OAAuB;AACvD,SAAK,IAAI,MAAM,MAA0B,KAAsC;AAG/E,UAAM,QAAQ,mBAAK,kCAAiC,IAAI,MAAM,IAAI;AAClE,QAAI,OAAO;AACV,YAAM,8BAA8B,EAAE,KAAK,GAAG,KAAK;AACnD,yBAAK,kCAAiC,OAAO,MAAM,IAAI;AAAA,IACxD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAA4B,OAAuB;AACzD,SAAK,OAAO,MAAM,IAAwB;AAC1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAa,UAA8C,OAAuD;AACjH,UAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;AAElC,QAAI,OAAO;AACV,YAAM,MAAM,UAAU,KAAK;AAAA,IAC5B,OAAO;AACN,UAAI,CAAC,QAAQ,MAAM,KAAK,GAAG;AAC1B,cAAM,IAAI,UAAU,aAAa,MAAM,IAAI,oBAAoB,OAAO,MAAM,KAAK,CAAC,EAAE;AAAA,MACrF;AAEA,yBAAK,kCAAiC,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,IAClH;AAAA,EACD;AACD;AA/IU;AAJ0E;AAA7E,IAAM,gBAAN","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport { isClass } from '@sapphire/utilities';\nimport { join } from 'path';\nimport { LoaderError } from '../errors/LoaderError';\nimport { resolvePath, type Path } from '../internal/Path';\nimport { getRootData } from '../internal/RootScan';\nimport { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constants';\nimport type { Piece } from './Piece';\nimport type { Store, StoreManuallyRegisteredPiece } from './Store';\n\n/**\n * A strict-typed store registry. This is available in {@link container}.\n * @since 2.1.0\n * @example\n * ```typescript\n * // Adding new stores\n *\n * // Register the store:\n * container.stores.register(new RouteStore());\n *\n * // Augment Sapphire to add the new store, in case of a JavaScript\n * // project, this can be moved to an `Augments.d.ts` (or any other name)\n * // file somewhere:\n * declare module '@sapphire/pieces' {\n * export interface StoreRegistryEntries {\n * routes: RouteStore;\n * }\n * }\n * ```\n */\nexport class StoreRegistry extends Collection<StoreRegistryKey, StoreRegistryValue> {\n\t/**\n\t * The queue of pieces to load.\n\t */\n\treadonly #pendingManuallyRegisteredPieces = new Collection<StoreRegistryKey, StoreManuallyRegisteredPiece<StoreRegistryKey>[]>();\n\n\t/**\n\t * Loads all the registered stores.\n\t * @since 2.1.0\n\t */\n\tpublic async load() {\n\t\tconst promises: Promise<unknown>[] = [];\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tpromises.push(store.loadAll());\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Registers all user directories from the process working directory, the default value is obtained by assuming\n\t * CommonJS (high accuracy) but with fallback for ECMAScript Modules (reads package.json's `main` entry, fallbacks\n\t * to `process.cwd()`).\n\t *\n\t * By default, if you have this folder structure:\n\t * ```\n\t * /home/me/my-bot\n\t * ├─ src\n\t * │ ├─ commands\n\t * │ ├─ events\n\t * │ └─ main.js\n\t * └─ package.json\n\t * ```\n\t *\n\t * And you run `node src/main.js`, the directories `/home/me/my-bot/src/commands` and `/home/me/my-bot/src/events` will\n\t * be registered for the commands and events stores respectively, since both directories are located in the same\n\t * directory as your main file.\n\t *\n\t * **Note**: this also registers directories for all other stores, even if they don't have a folder, this allows you\n\t * to create new pieces and hot-load them later anytime.\n\t * @since 2.1.0\n\t * @param rootDirectory The root directory to register pieces at.\n\t */\n\tpublic registerPath(rootDirectory: Path = getRootData().root) {\n\t\tconst root = resolvePath(rootDirectory);\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tstore.registerPath(join(root, store.name));\n\t\t}\n\t}\n\n\t/**\n\t * Registers a store.\n\t *\n\t * @remarks\n\t *\n\t * - This method will allow {@linkcode StoreRegistry} to manage the store, meaning:\n\t * - {@linkcode StoreRegistry.registerPath()} will call the store's\n\t * {@linkcode Store.registerPath() registerPath()} method on call.\n\t * - {@linkcode StoreRegistry.load()} will call the store's {@linkcode Store.load() load()} method on call.\n\t * - {@linkcode StoreRegistry.loadPiece()} will call the store's {@linkcode Store.loadPiece() loadPiece()} method\n\t * on call.\n\t * - This will also add all the manually registered pieces by {@linkcode StoreRegistry.loadPiece()} in the store.\n\t *\n\t * It is generally recommended to register a store as early as possible, before any of the aforementioned methods\n\t * are called, otherwise you will have to manually call the aforementioned methods for the store to work properly.\n\t *\n\t * If there were manually registered pieces for this store with {@linkcode StoreRegistry.loadPiece()}, this method\n\t * will add them to the store and delete the queue. Note, however, that this method will not call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method, and as such, the pieces will not be loaded until\n\t * {@linkcode Store.loadAll()} is called.\n\t *\n\t * @since 2.1.0\n\t * @param store The store to register.\n\t */\n\tpublic register<T extends Piece>(store: Store<T>): this {\n\t\tthis.set(store.name as StoreRegistryKey, store as unknown as StoreRegistryValue);\n\n\t\t// If there was a queue for this store, add it to the store and delete the queue:\n\t\tconst queue = this.#pendingManuallyRegisteredPieces.get(store.name);\n\t\tif (queue) {\n\t\t\tstore[ManuallyRegisteredPiecesSymbol].push(...queue);\n\t\t\tthis.#pendingManuallyRegisteredPieces.delete(store.name);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Deregisters a store.\n\t * @since 2.1.0\n\t * @param store The store to deregister.\n\t */\n\tpublic deregister<T extends Piece>(store: Store<T>): this {\n\t\tthis.delete(store.name as StoreRegistryKey);\n\t\treturn this;\n\t}\n\n\t/**\n\t * If the store was {@link StoreRegistry.register registered}, this method will call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method.\n\t *\n\t * If it was called, the entry will be loaded immediately without queueing.\n\t *\n\t * @remarks\n\t *\n\t * - Pieces loaded this way will have their {@linkcode Piece.Context.root root} and\n\t * {@linkcode Piece.Context.path path} set to {@linkcode VirtualPath}, and as such, cannot be reloaded.\n\t * - This method is useful in environments where file system access is limited or unavailable, such as when using\n\t * {@link https://en.wikipedia.org/wiki/Serverless_computing Serverless Computing}.\n\t * - This method will not throw an error if a store with the given name does not exist, it will simply be queued\n\t * until it's registered.\n\t * - This method will always throw a {@link TypeError} if `entry.piece` is not a class.\n\t * - If the store is registered, this method will always throw a {@linkcode LoaderError} if the piece does not\n\t * extend the registered {@linkcode Store.Constructor store's piece constructor}.\n\t * - This operation is atomic, if any of the above errors are thrown, the piece will not be loaded.\n\t *\n\t * @seealso {@linkcode Store.loadPiece()}\n\t * @since 3.8.0\n\t * @param entry The entry to load.\n\t * @example\n\t * ```typescript\n\t * import { container } from '@sapphire/pieces';\n\t *\n\t * class PingCommand extends Command {\n\t * // ...\n\t * }\n\t *\n\t * container.stores.loadPiece({\n\t * store: 'commands',\n\t * name: 'ping',\n\t * piece: PingCommand\n\t * });\n\t * ```\n\t */\n\tpublic async loadPiece<StoreName extends StoreRegistryKey>(entry: StoreManagerManuallyRegisteredPiece<StoreName>) {\n\t\tconst store = this.get(entry.store) as Store<Piece, StoreName> | undefined;\n\n\t\tif (store) {\n\t\t\tawait store.loadPiece(entry);\n\t\t} else {\n\t\t\tif (!isClass(entry.piece)) {\n\t\t\t\tthrow new TypeError(`The piece ${entry.name} is not a Class. ${String(entry.piece)}`);\n\t\t\t}\n\n\t\t\tthis.#pendingManuallyRegisteredPieces.ensure(entry.store, () => []).push({ name: entry.name, piece: entry.piece });\n\t\t}\n\t}\n}\n\nexport interface StoreRegistry {\n\tget<K extends StoreRegistryKey>(key: K): StoreRegistryEntries[K];\n\tget(key: string): undefined;\n\thas(key: StoreRegistryKey): true;\n\thas(key: string): false;\n}\n\n/**\n * A type utility to get the keys of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryKey = keyof StoreRegistryEntries;\n\n/**\n * A type utility to get the values of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryValue = StoreRegistryEntries[StoreRegistryKey];\n\n/**\n * The {@link StoreRegistry}'s registry, use module augmentation against this interface when adding new stores.\n * @since 2.1.0\n */\nexport interface StoreRegistryEntries {}\n\n/**\n * An entry for a manually registered piece using {@linkcode StoreRegistry.loadPiece()}.\n * @seealso {@linkcode StoreRegistry.loadPiece()}\n * @since 3.8.0\n */\nexport interface StoreManagerManuallyRegisteredPiece<StoreName extends StoreRegistryKey> extends StoreManuallyRegisteredPiece<StoreName> {\n\tstore: StoreName;\n}\n\n/**\n * Type utility to get the {@linkcode Store} given its name.\n * @since 3.10.0\n */\nexport type StoreOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Store<Piece<Piece.Options, StoreName>>\n\t: StoreRegistryEntries[StoreName];\n\n/**\n * Type utility to get the {@linkcode Piece} given its {@linkcode Store}'s name.\n * @since 3.10.0\n */\nexport type PieceOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Piece<Piece.Options, StoreName>\n\t: StoreRegistryEntries[StoreName] extends Store<infer PieceType>\n\t ? PieceType\n\t : Piece<Piece.Options, StoreName>;\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/StoreRegistry.ts"],"names":[],"mappings":";;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAA4B;AAC5B,SAAS,mBAA8B;AACvC,SAAS,mBAAmB;AAC5B,SAAS,sCAAmD;AAN5D;AA8BO,IAAM,iBAAN,MAAM,uBAAsB,WAAiD;AAAA,EAA7E;AAAA;AAIN;AAAA;AAAA;AAAA,uBAAS,kCAAmC,IAAI,WAA+E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/H,MAAa,OAAO;AACnB,UAAM,WAA+B,CAAC;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,eAAS,KAAK,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,aAAa,gBAAsB,YAAY,EAAE,MAAM;AAC7D,UAAM,OAAO,YAAY,aAAa;AACtC,eAAW,SAAS,KAAK,OAAO,GAAqC;AACpE,YAAM,aAAa,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IAC1C;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BO,SAA0B,OAAuB;AACvD,SAAK,IAAI,MAAM,MAA0B,KAAsC;AAG/E,UAAM,QAAQ,mBAAK,kCAAiC,IAAI,MAAM,IAAI;AAClE,QAAI,OAAO;AACV,YAAM,8BAA8B,EAAE,KAAK,GAAG,KAAK;AACnD,yBAAK,kCAAiC,OAAO,MAAM,IAAI;AAAA,IACxD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAA4B,OAAuB;AACzD,SAAK,OAAO,MAAM,IAAwB;AAC1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAa,UAA8C,OAAuD;AACjH,UAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;AAElC,QAAI,OAAO;AACV,YAAM,MAAM,UAAU,KAAK;AAAA,IAC5B,OAAO;AACN,UAAI,CAAC,QAAQ,MAAM,KAAK,GAAG;AAC1B,cAAM,IAAI,UAAU,aAAa,MAAM,IAAI,oBAAoB,OAAO,MAAM,KAAK,CAAC,EAAE;AAAA,MACrF;AAEA,yBAAK,kCAAiC,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,IAClH;AAAA,EACD;AACD;AA/IU;AAJ0E;AAA7E,IAAM,gBAAN","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport { isClass } from '@sapphire/utilities';\nimport { join } from 'path';\nimport { LoaderError } from '../errors/LoaderError';\nimport { resolvePath, type Path } from '../internal/Path';\nimport { getRootData } from '../internal/RootScan';\nimport { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constants';\nimport type { Piece } from './Piece';\nimport type { Store, StoreManuallyRegisteredPiece } from './Store';\n\n/**\n * A strict-typed store registry. This is available in {@link container}.\n * @since 2.1.0\n * @example\n * ```typescript\n * // Adding new stores\n *\n * // Register the store:\n * container.stores.register(new RouteStore());\n *\n * // Augment Sapphire to add the new store, in case of a JavaScript\n * // project, this can be moved to an `Augments.d.ts` (or any other name)\n * // file somewhere:\n * declare module '@sapphire/pieces' {\n * export interface StoreRegistryEntries {\n * routes: RouteStore;\n * }\n * }\n * ```\n */\nexport class StoreRegistry extends Collection<StoreRegistryKey, StoreRegistryValue> {\n\t/**\n\t * The queue of pieces to load.\n\t */\n\treadonly #pendingManuallyRegisteredPieces = new Collection<StoreRegistryKey, StoreManuallyRegisteredPiece<StoreRegistryKey>[]>();\n\n\t/**\n\t * Loads all the registered stores.\n\t * @since 2.1.0\n\t */\n\tpublic async load() {\n\t\tconst promises: Promise<unknown>[] = [];\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tpromises.push(store.loadAll());\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Registers all user directories from the process working directory, the default value is obtained by assuming\n\t * CommonJS (high accuracy) but with fallback for ECMAScript Modules (reads package.json's `main` entry, fallbacks\n\t * to `process.cwd()`).\n\t *\n\t * By default, if you have this folder structure:\n\t * ```\n\t * /home/me/my-bot\n\t * ├─ src\n\t * │ ├─ commands\n\t * │ ├─ events\n\t * │ └─ main.js\n\t * └─ package.json\n\t * ```\n\t *\n\t * And you run `node src/main.js`, the directories `/home/me/my-bot/src/commands` and `/home/me/my-bot/src/events` will\n\t * be registered for the commands and events stores respectively, since both directories are located in the same\n\t * directory as your main file.\n\t *\n\t * **Note**: this also registers directories for all other stores, even if they don't have a folder, this allows you\n\t * to create new pieces and hot-load them later anytime.\n\t * @since 2.1.0\n\t * @param rootDirectory The root directory to register pieces at.\n\t */\n\tpublic registerPath(rootDirectory: Path = getRootData().root) {\n\t\tconst root = resolvePath(rootDirectory);\n\t\tfor (const store of this.values() as IterableIterator<Store<Piece>>) {\n\t\t\tstore.registerPath(join(root, store.name));\n\t\t}\n\t}\n\n\t/**\n\t * Registers a store.\n\t *\n\t * @remarks\n\t *\n\t * - This method will allow {@linkcode StoreRegistry} to manage the store, meaning:\n\t * - {@linkcode StoreRegistry.registerPath()} will call the store's\n\t * {@linkcode Store.registerPath() registerPath()} method on call.\n\t * - {@linkcode StoreRegistry.load()} will call the store's {@linkcode Store.load() load()} method on call.\n\t * - {@linkcode StoreRegistry.loadPiece()} will call the store's {@linkcode Store.loadPiece() loadPiece()} method\n\t * on call.\n\t * - This will also add all the manually registered pieces by {@linkcode StoreRegistry.loadPiece()} in the store.\n\t *\n\t * It is generally recommended to register a store as early as possible, before any of the aforementioned methods\n\t * are called, otherwise you will have to manually call the aforementioned methods for the store to work properly.\n\t *\n\t * If there were manually registered pieces for this store with {@linkcode StoreRegistry.loadPiece()}, this method\n\t * will add them to the store and delete the queue. Note, however, that this method will not call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method, and as such, the pieces will not be loaded until\n\t * {@linkcode Store.loadAll()} is called.\n\t *\n\t * @since 2.1.0\n\t * @param store The store to register.\n\t */\n\tpublic register<T extends Piece>(store: Store<T>): this {\n\t\tthis.set(store.name as StoreRegistryKey, store as unknown as StoreRegistryValue);\n\n\t\t// If there was a queue for this store, add it to the store and delete the queue:\n\t\tconst queue = this.#pendingManuallyRegisteredPieces.get(store.name);\n\t\tif (queue) {\n\t\t\tstore[ManuallyRegisteredPiecesSymbol].push(...queue);\n\t\t\tthis.#pendingManuallyRegisteredPieces.delete(store.name);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Deregisters a store.\n\t * @since 2.1.0\n\t * @param store The store to deregister.\n\t */\n\tpublic deregister<T extends Piece>(store: Store<T>): this {\n\t\tthis.delete(store.name as StoreRegistryKey);\n\t\treturn this;\n\t}\n\n\t/**\n\t * If the store was {@link StoreRegistry.register registered}, this method will call the store's\n\t * {@linkcode Store.loadPiece() loadPiece()} method.\n\t *\n\t * If it was called, the entry will be loaded immediately without queueing.\n\t *\n\t * @remarks\n\t *\n\t * - Pieces loaded this way will have their {@linkcode Piece.Context.root root} and\n\t * {@linkcode Piece.Context.path path} set to {@linkcode VirtualPath}, and as such, cannot be reloaded.\n\t * - This method is useful in environments where file system access is limited or unavailable, such as when using\n\t * {@link https://en.wikipedia.org/wiki/Serverless_computing Serverless Computing}.\n\t * - This method will not throw an error if a store with the given name does not exist, it will simply be queued\n\t * until it's registered.\n\t * - This method will always throw a {@link TypeError} if `entry.piece` is not a class.\n\t * - If the store is registered, this method will always throw a {@linkcode LoaderError} if the piece does not\n\t * extend the registered {@linkcode Store.Constructor store's piece constructor}.\n\t * - This operation is atomic, if any of the above errors are thrown, the piece will not be loaded.\n\t *\n\t * @seealso {@linkcode Store.loadPiece()}\n\t * @since 3.8.0\n\t * @param entry The entry to load.\n\t * @example\n\t * ```typescript\n\t * import { container } from '@sapphire/pieces';\n\t *\n\t * class PingCommand extends Command {\n\t * // ...\n\t * }\n\t *\n\t * container.stores.loadPiece({\n\t * store: 'commands',\n\t * name: 'ping',\n\t * piece: PingCommand\n\t * });\n\t * ```\n\t */\n\tpublic async loadPiece<StoreName extends StoreRegistryKey>(entry: StoreManagerManuallyRegisteredPiece<StoreName>) {\n\t\tconst store = this.get(entry.store) as Store<Piece, StoreName> | undefined;\n\n\t\tif (store) {\n\t\t\tawait store.loadPiece(entry);\n\t\t} else {\n\t\t\tif (!isClass(entry.piece)) {\n\t\t\t\tthrow new TypeError(`The piece ${entry.name} is not a Class. ${String(entry.piece)}`);\n\t\t\t}\n\n\t\t\tthis.#pendingManuallyRegisteredPieces.ensure(entry.store, () => []).push({ name: entry.name, piece: entry.piece });\n\t\t}\n\t}\n}\n\nexport interface StoreRegistry {\n\tget<K extends StoreRegistryKey>(key: K): StoreRegistryEntries[K];\n\tget(key: string): undefined;\n\thas(key: StoreRegistryKey): true;\n\thas(key: string): false;\n}\n\n/**\n * A type utility to get the keys of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryKey = keyof StoreRegistryEntries;\n\n/**\n * A type utility to get the values of {@linkcode StoreRegistryEntries}.\n * @since 3.10.0\n */\nexport type StoreRegistryValue = StoreRegistryEntries[StoreRegistryKey];\n\n/**\n * The {@link StoreRegistry}'s registry, use module augmentation against this interface when adding new stores.\n * @since 2.1.0\n */\nexport interface StoreRegistryEntries {}\n\n/**\n * An entry for a manually registered piece using {@linkcode StoreRegistry.loadPiece()}.\n * @seealso {@linkcode StoreRegistry.loadPiece()}\n * @since 3.8.0\n */\nexport interface StoreManagerManuallyRegisteredPiece<StoreName extends StoreRegistryKey> extends StoreManuallyRegisteredPiece<StoreName> {\n\tstore: StoreName;\n}\n\n/**\n * Type utility to get the {@linkcode Store} given its name.\n * @since 3.10.0\n */\nexport type StoreOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Store<Piece<Piece.Options, StoreName>>\n\t: StoreRegistryEntries[StoreName];\n\n/**\n * Type utility to get the {@linkcode Piece} given its {@linkcode Store}'s name.\n * @since 3.10.0\n */\nexport type PieceOf<StoreName extends StoreRegistryKey> = StoreRegistryKey extends never\n\t? Piece<Piece.Options, StoreName>\n\t: StoreRegistryEntries[StoreName] extends Store<infer PieceType>\n\t\t? PieceType\n\t\t: Piece<Piece.Options, StoreName>;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapphire/pieces",
3
- "version": "4.1.0",
3
+ "version": "4.1.1-next.af3fb0d.0",
4
4
  "description": "Sapphire's piece loader.",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/esm/index.mjs",
@@ -42,26 +42,26 @@
42
42
  "@commitlint/config-conventional": "^18.4.3",
43
43
  "@favware/cliff-jumper": "^2.2.3",
44
44
  "@favware/npm-deprecate": "^1.0.7",
45
- "@favware/rollup-type-bundler": "^3.2.0",
45
+ "@favware/rollup-type-bundler": "^3.2.1",
46
46
  "@sapphire/eslint-config": "^5.0.3",
47
47
  "@sapphire/prettier-config": "^2.0.0",
48
48
  "@sapphire/ts-config": "^5.0.0",
49
- "@types/node": "^20.10.3",
50
- "@typescript-eslint/eslint-plugin": "^6.13.2",
51
- "@typescript-eslint/parser": "^6.13.2",
49
+ "@types/node": "^20.10.4",
50
+ "@typescript-eslint/eslint-plugin": "^6.14.0",
51
+ "@typescript-eslint/parser": "^6.14.0",
52
52
  "concurrently": "^8.2.2",
53
53
  "cz-conventional-changelog": "^3.3.0",
54
54
  "esbuild-plugin-file-path-extensions": "^2.0.0",
55
- "eslint": "^8.55.0",
55
+ "eslint": "^8.56.0",
56
56
  "eslint-config-prettier": "^9.1.0",
57
57
  "eslint-plugin-prettier": "^5.0.1",
58
58
  "lint-staged": "^15.2.0",
59
- "prettier": "^3.1.0",
59
+ "prettier": "^3.1.1",
60
60
  "rimraf": "^5.0.5",
61
61
  "tsup": "^8.0.1",
62
62
  "typedoc": "^0.25.4",
63
63
  "typedoc-json-parser": "^9.0.1",
64
- "typescript": "^5.3.2"
64
+ "typescript": "^5.3.3"
65
65
  },
66
66
  "repository": {
67
67
  "type": "git",