@sapphire/pieces 4.2.3-next.41f300a.0 → 4.2.3-next.567c7f4
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/dist/cjs/lib/errors/LoaderError.cjs +1 -4
- package/dist/cjs/lib/errors/LoaderError.cjs.map +1 -1
- package/dist/cjs/lib/errors/MissingExportsError.cjs +1 -4
- package/dist/cjs/lib/errors/MissingExportsError.cjs.map +1 -1
- package/dist/cjs/lib/internal/Path.cjs +1 -2
- package/dist/cjs/lib/internal/Path.cjs.map +1 -1
- package/dist/cjs/lib/internal/RootScan.cjs +6 -12
- package/dist/cjs/lib/internal/RootScan.cjs.map +1 -1
- package/dist/cjs/lib/strategies/LoaderStrategy.cjs +8 -18
- package/dist/cjs/lib/strategies/LoaderStrategy.cjs.map +1 -1
- package/dist/cjs/lib/strategies/Shared.cjs +1 -2
- package/dist/cjs/lib/strategies/Shared.cjs.map +1 -1
- package/dist/cjs/lib/structures/AliasPiece.cjs +1 -4
- package/dist/cjs/lib/structures/AliasPiece.cjs.map +1 -1
- package/dist/cjs/lib/structures/AliasStore.cjs +2 -6
- package/dist/cjs/lib/structures/AliasStore.cjs.map +1 -1
- package/dist/cjs/lib/structures/Piece.cjs +1 -4
- package/dist/cjs/lib/structures/Piece.cjs.map +1 -1
- package/dist/cjs/lib/structures/PieceLocation.cjs +1 -4
- package/dist/cjs/lib/structures/PieceLocation.cjs.map +1 -1
- package/dist/cjs/lib/structures/Store.cjs +14 -32
- package/dist/cjs/lib/structures/Store.cjs.map +1 -1
- package/dist/cjs/lib/structures/StoreRegistry.cjs +6 -13
- package/dist/cjs/lib/structures/StoreRegistry.cjs.map +1 -1
- package/dist/esm/chunk-KFLDEQ5J.mjs +21 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/lib/errors/LoaderError.mjs +1 -1
- package/dist/esm/lib/errors/MissingExportsError.mjs +1 -1
- package/dist/esm/lib/internal/Path.mjs +2 -3
- package/dist/esm/lib/internal/Path.mjs.map +1 -1
- package/dist/esm/lib/internal/RootScan.mjs +7 -13
- package/dist/esm/lib/internal/RootScan.mjs.map +1 -1
- package/dist/esm/lib/internal/constants.mjs +1 -1
- package/dist/esm/lib/shared/Container.mjs +1 -1
- package/dist/esm/lib/strategies/LoaderStrategy.mjs +7 -13
- package/dist/esm/lib/strategies/LoaderStrategy.mjs.map +1 -1
- package/dist/esm/lib/strategies/Shared.mjs +2 -3
- package/dist/esm/lib/strategies/Shared.mjs.map +1 -1
- package/dist/esm/lib/structures/AliasPiece.mjs +1 -1
- package/dist/esm/lib/structures/AliasStore.mjs +2 -3
- package/dist/esm/lib/structures/AliasStore.mjs.map +1 -1
- package/dist/esm/lib/structures/Piece.mjs +1 -1
- package/dist/esm/lib/structures/PieceLocation.mjs +1 -1
- package/dist/esm/lib/structures/Store.mjs +7 -11
- package/dist/esm/lib/structures/Store.mjs.map +1 -1
- package/dist/esm/lib/structures/StoreRegistry.mjs +1 -1
- package/package.json +17 -17
- package/dist/esm/chunk-LIQV5WSN.mjs +0 -36
- /package/dist/esm/{chunk-LIQV5WSN.mjs.map → chunk-KFLDEQ5J.mjs.map} +0 -0
|
@@ -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,iBAAW,SAAS,OAAO;AAC1B,cAAM,8BAA8B,EAAE,IAAI,MAAM,MAAM,KAAK;AAAA,MAC5D;AAEA,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;AAlJU;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\tfor (const entry of queue) {\n\t\t\t\tstore[ManuallyRegisteredPiecesSymbol].set(entry.name, entry);\n\t\t\t}\n\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
|
+
{"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,iBAAW,SAAS,OAAO;AAC1B,cAAM,8BAA8B,EAAE,IAAI,MAAM,MAAM,KAAK;AAAA,MAC5D;AAEA,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;AAlJU;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\tfor (const entry of queue) {\n\t\t\t\tstore[ManuallyRegisteredPiecesSymbol].set(entry.name, entry);\n\t\t\t}\n\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"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __typeError = (msg) => {
|
|
3
|
+
throw TypeError(msg);
|
|
4
|
+
};
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
14
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
15
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
16
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
17
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
18
|
+
|
|
19
|
+
export { __name, __privateAdd, __privateGet, __privateSet, __publicField, __require };
|
|
20
|
+
//# sourceMappingURL=out.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-KFLDEQ5J.mjs.map
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name, __publicField } from '../../chunk-
|
|
1
|
+
import { __name, __publicField } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { LoaderError, LoaderErrorType } from './LoaderError.mjs';
|
|
3
3
|
|
|
4
4
|
var _MissingExportsError = class _MissingExportsError extends LoaderError {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { __name } from '../../chunk-
|
|
1
|
+
import { __name } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
|
|
4
4
|
function resolvePath(path) {
|
|
5
|
-
if (typeof path === "string")
|
|
6
|
-
return path;
|
|
5
|
+
if (typeof path === "string") return path;
|
|
7
6
|
return fileURLToPath(path);
|
|
8
7
|
}
|
|
9
8
|
__name(resolvePath, "resolvePath");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/internal/Path.ts"],"names":[],"mappings":";;;;;AAAA,SAAS,qBAAqB;AAIvB,SAAS,YAAY,MAAoB;AAC/C,MAAI,OAAO,SAAS
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/internal/Path.ts"],"names":[],"mappings":";;;;;AAAA,SAAS,qBAAqB;AAIvB,SAAS,YAAY,MAAoB;AAC/C,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,SAAO,cAAc,IAAI;AAC1B;AAHgB","sourcesContent":["import { fileURLToPath } from 'node:url';\n\nexport type Path = string | URL;\n\nexport function resolvePath(path: Path): string {\n\tif (typeof path === 'string') return path;\n\treturn fileURLToPath(path);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name } from '../../chunk-
|
|
1
|
+
import { __name } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
3
|
import { dirname, join } from 'path';
|
|
4
4
|
|
|
@@ -22,23 +22,17 @@ function parseRootData() {
|
|
|
22
22
|
const { main: packageMain, module: packageModule, type: packageType } = file;
|
|
23
23
|
const lowerCasedType = packageType?.toLowerCase();
|
|
24
24
|
if (lowerCasedType === "commonjs") {
|
|
25
|
-
if (packageMain)
|
|
26
|
-
|
|
27
|
-
if (packageModule)
|
|
28
|
-
return { root: dirnameWithPath(cwd, packageModule), type: "CommonJS" };
|
|
25
|
+
if (packageMain) return { root: dirnameWithPath(cwd, packageMain), type: "CommonJS" };
|
|
26
|
+
if (packageModule) return { root: dirnameWithPath(cwd, packageModule), type: "CommonJS" };
|
|
29
27
|
return { root: cwd, type: "CommonJS" };
|
|
30
28
|
}
|
|
31
29
|
if (lowerCasedType === "module") {
|
|
32
|
-
if (packageMain)
|
|
33
|
-
|
|
34
|
-
if (packageModule)
|
|
35
|
-
return { root: dirnameWithPath(cwd, packageModule), type: "ESM" };
|
|
30
|
+
if (packageMain) return { root: dirnameWithPath(cwd, packageMain), type: "ESM" };
|
|
31
|
+
if (packageModule) return { root: dirnameWithPath(cwd, packageModule), type: "ESM" };
|
|
36
32
|
return { root: cwd, type: "ESM" };
|
|
37
33
|
}
|
|
38
|
-
if (packageMain)
|
|
39
|
-
|
|
40
|
-
if (packageModule)
|
|
41
|
-
return { root: dirnameWithPath(cwd, packageModule), type: "ESM" };
|
|
34
|
+
if (packageMain) return { root: dirnameWithPath(cwd, packageMain), type: "CommonJS" };
|
|
35
|
+
if (packageModule) return { root: dirnameWithPath(cwd, packageModule), type: "ESM" };
|
|
42
36
|
return { root: cwd, type: "CommonJS" };
|
|
43
37
|
}
|
|
44
38
|
__name(parseRootData, "parseRootData");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/internal/RootScan.ts"],"names":[],"mappings":";;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AA2B9B,IAAI,OAAwB;AAS5B,SAAS,gBAAgB,KAAa,cAAsB;AAC3D,SAAO,QAAQ,KAAK,KAAK,YAAY,CAAC;AACvC;AAFS;AAIF,SAAS,cAAwB;AACvC,SAAQ,SAAS,cAAc;AAChC;AAFgB;AAmCT,SAAS,gBAA0B;AACzC,QAAM,MAAM,QAAQ,IAAI;AAExB,MAAI;AAEJ,MAAI;AACH,WAAO,KAAK,MAAM,aAAa,KAAK,KAAK,cAAc,GAAG,MAAM,CAAC;AAAA,EAClE,SAAS,OAAO;AACf,WAAO,EAAE,MAAM,KAAK,MAAM,WAAW;AAAA,EACtC;AAEA,QAAM,EAAE,MAAM,aAAa,QAAQ,eAAe,MAAM,YAAY,IAAI;AAExE,QAAM,iBAAiB,aAAa,YAAY;AAEhD,MAAI,mBAAmB,YAAY;AAClC,QAAI
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/internal/RootScan.ts"],"names":[],"mappings":";;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AA2B9B,IAAI,OAAwB;AAS5B,SAAS,gBAAgB,KAAa,cAAsB;AAC3D,SAAO,QAAQ,KAAK,KAAK,YAAY,CAAC;AACvC;AAFS;AAIF,SAAS,cAAwB;AACvC,SAAQ,SAAS,cAAc;AAChC;AAFgB;AAmCT,SAAS,gBAA0B;AACzC,QAAM,MAAM,QAAQ,IAAI;AAExB,MAAI;AAEJ,MAAI;AACH,WAAO,KAAK,MAAM,aAAa,KAAK,KAAK,cAAc,GAAG,MAAM,CAAC;AAAA,EAClE,SAAS,OAAO;AACf,WAAO,EAAE,MAAM,KAAK,MAAM,WAAW;AAAA,EACtC;AAEA,QAAM,EAAE,MAAM,aAAa,QAAQ,eAAe,MAAM,YAAY,IAAI;AAExE,QAAM,iBAAiB,aAAa,YAAY;AAEhD,MAAI,mBAAmB,YAAY;AAClC,QAAI,YAAa,QAAO,EAAE,MAAM,gBAAgB,KAAK,WAAW,GAAG,MAAM,WAAW;AACpF,QAAI,cAAe,QAAO,EAAE,MAAM,gBAAgB,KAAK,aAAa,GAAG,MAAM,WAAW;AACxF,WAAO,EAAE,MAAM,KAAK,MAAM,WAAW;AAAA,EACtC;AAEA,MAAI,mBAAmB,UAAU;AAChC,QAAI,YAAa,QAAO,EAAE,MAAM,gBAAgB,KAAK,WAAW,GAAG,MAAM,MAAM;AAC/E,QAAI,cAAe,QAAO,EAAE,MAAM,gBAAgB,KAAK,aAAa,GAAG,MAAM,MAAM;AACnF,WAAO,EAAE,MAAM,KAAK,MAAM,MAAM;AAAA,EACjC;AAEA,MAAI,YAAa,QAAO,EAAE,MAAM,gBAAgB,KAAK,WAAW,GAAG,MAAM,WAAW;AACpF,MAAI,cAAe,QAAO,EAAE,MAAM,gBAAgB,KAAK,aAAa,GAAG,MAAM,MAAM;AAEnF,SAAO,EAAE,MAAM,KAAK,MAAM,WAAW;AACtC;AA/BgB","sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\n\n/**\n * Represents a partial package.json object.\n */\ntype PartialPackageJson = Partial<{\n\tmain: string;\n\tmodule: string;\n\ttype: 'commonjs' | 'module';\n}>;\n\n/**\n * Represents the root data.\n */\nexport interface RootData {\n\t/**\n\t * The root directory.\n\t */\n\troot: string;\n\n\t/**\n\t * The type of the module system used.\n\t * It can be either 'ESM' or 'CommonJS'.\n\t */\n\ttype: 'ESM' | 'CommonJS';\n}\n\nlet data: RootData | null = null;\n\n/**\n * Returns the directory name of a given path by joining the current working directory (cwd) with the joinable path.\n * @private\n * @param cwd - The current working directory.\n * @param joinablePath - The path to be joined with the cwd.\n * @returns The directory name of the joined path.\n */\nfunction dirnameWithPath(cwd: string, joinablePath: string) {\n\treturn dirname(join(cwd, joinablePath));\n}\n\nexport function getRootData(): RootData {\n\treturn (data ??= parseRootData());\n}\n\n/**\n * Retrieves the root data of the project.\n *\n * This function reads the `package.json` file in the current working directory and determines the root path and type\n * of the project.\n *\n * - If the `package.json` file is not found or cannot be parsed, it assumes the project is using CommonJS and\n * the current working directory is used as the root\n *\n * - If the project `type` is specified as `\"commonjs\"` or `\"module\"` in the `package.json`, it uses the corresponding\n * `main` or `module` file path as the root.\n *\n * - If there is no `main` or `module` then it uses the current working directory as the root, while retaining the\n * matching `CommonJS` or `ESM` based on the `type`\n *\n * - If the main or module file path is not specified, it uses the current working directory as the root.\n *\n * The following table shows how different situations resolve to different root data\n *\n * | fields | resolved as |\n * |--------------------------|-------------|\n * | type=commonjs && main | CommonJS |\n * | type=commonjs && module | CommonJS |\n * | type=module && main | ESM |\n * | type=module && module | ESM |\n * | type=undefined && main | CommonJS |\n * | type=undefined && module | ESM |\n * | no package.json on cwd | CommonJS |\n *\n * @returns The root data object containing the root path and the type of the project.\n */\nexport function parseRootData(): RootData {\n\tconst cwd = process.cwd();\n\n\tlet file: PartialPackageJson | undefined;\n\n\ttry {\n\t\tfile = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8')) as PartialPackageJson;\n\t} catch (error) {\n\t\treturn { root: cwd, type: 'CommonJS' };\n\t}\n\n\tconst { main: packageMain, module: packageModule, type: packageType } = file;\n\n\tconst lowerCasedType = packageType?.toLowerCase() as PartialPackageJson['type'];\n\n\tif (lowerCasedType === 'commonjs') {\n\t\tif (packageMain) return { root: dirnameWithPath(cwd, packageMain), type: 'CommonJS' };\n\t\tif (packageModule) return { root: dirnameWithPath(cwd, packageModule), type: 'CommonJS' };\n\t\treturn { root: cwd, type: 'CommonJS' };\n\t}\n\n\tif (lowerCasedType === 'module') {\n\t\tif (packageMain) return { root: dirnameWithPath(cwd, packageMain), type: 'ESM' };\n\t\tif (packageModule) return { root: dirnameWithPath(cwd, packageModule), type: 'ESM' };\n\t\treturn { root: cwd, type: 'ESM' };\n\t}\n\n\tif (packageMain) return { root: dirnameWithPath(cwd, packageMain), type: 'CommonJS' };\n\tif (packageModule) return { root: dirnameWithPath(cwd, packageModule), type: 'ESM' };\n\n\treturn { root: cwd, type: 'CommonJS' };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name, __publicField, __require } from '../../chunk-
|
|
1
|
+
import { __name, __publicField, __require } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { isNullish } from '@sapphire/utilities';
|
|
3
3
|
import { opendir } from 'fs/promises';
|
|
4
4
|
import { extname, basename, join } from 'path';
|
|
@@ -24,13 +24,10 @@ var _LoaderStrategy = class _LoaderStrategy {
|
|
|
24
24
|
}
|
|
25
25
|
filter(path) {
|
|
26
26
|
const extension = extname(path);
|
|
27
|
-
if (!this.supportedExtensions.includes(extension))
|
|
28
|
-
|
|
29
|
-
if (this.filterDtsFiles && path.endsWith(".d.ts"))
|
|
30
|
-
return null;
|
|
27
|
+
if (!this.supportedExtensions.includes(extension)) return null;
|
|
28
|
+
if (this.filterDtsFiles && path.endsWith(".d.ts")) return null;
|
|
31
29
|
const name = basename(path, extension);
|
|
32
|
-
if (name === "" || name.startsWith("_"))
|
|
33
|
-
return null;
|
|
30
|
+
if (name === "" || name.startsWith("_")) return null;
|
|
34
31
|
return { extension, path, name };
|
|
35
32
|
}
|
|
36
33
|
async preload(file) {
|
|
@@ -83,14 +80,11 @@ var _LoaderStrategy = class _LoaderStrategy {
|
|
|
83
80
|
try {
|
|
84
81
|
const dir = await opendir(path);
|
|
85
82
|
for await (const item of dir) {
|
|
86
|
-
if (item.isFile())
|
|
87
|
-
|
|
88
|
-
else if (item.isDirectory())
|
|
89
|
-
yield* this.walk(store, join(dir.path, item.name), logger);
|
|
83
|
+
if (item.isFile()) yield join(dir.path, item.name);
|
|
84
|
+
else if (item.isDirectory()) yield* this.walk(store, join(dir.path, item.name), logger);
|
|
90
85
|
}
|
|
91
86
|
} catch (error) {
|
|
92
|
-
if (error.code !== "ENOENT")
|
|
93
|
-
this.onError(error, path);
|
|
87
|
+
if (error.code !== "ENOENT") this.onError(error, path);
|
|
94
88
|
}
|
|
95
89
|
}
|
|
96
90
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/strategies/LoaderStrategy.ts"],"names":[],"mappings":";;;;;;;AAAA,SAAS,iBAAiC;AAC1C,SAAS,eAAe;AACxB,SAAS,UAAU,SAAS,YAAY;AACxC,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAY1B,SAAS,cAAc,eAAe;AAM/B,IAAM,kBAAN,MAAM,gBAA8D;AAAA,EAKnE,cAAc;AAJrB,wBAAO,uBAAsB,YAAY,EAAE,SAAS;AACpD,wBAAO,uBAAsB,CAAC,OAAO,QAAQ,MAAM;AACnD,wBAAiB,kBAA0B;AAe1C,UAAM,oBACL,QAAQ,IAAI,SAAS,OAAO,IAAI,2BAA2B,CAAC;AAAA,IAC5D,QAAQ,IAAI,YAAY,MAAM;AAAA,IAC9B,CAAC,UAAU,QAAQ,IAAI,WAAW;AAAA,IAClC,SAAS,QAAQ;AAElB,QAAI,mBAAmB;AACtB,WAAK,oBAAoB,KAAK,OAAO,QAAQ,MAAM;AACnD,WAAK,iBAAiB;AAAA,IACvB;AAAA,EACD;AAAA,EAEO,OAAO,MAA4B;AAEzC,UAAM,YAAY,QAAQ,IAAI;AAC9B,QAAI,CAAC,KAAK,oBAAoB,SAAS,SAAS
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/strategies/LoaderStrategy.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNullish, type Awaitable } from '@sapphire/utilities';\nimport { opendir } from 'fs/promises';\nimport { basename, extname, join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { MissingExportsError } from '../errors/MissingExportsError';\nimport { getRootData } from '../internal/RootScan';\nimport { mjsImport } from '../internal/internal';\nimport type { Piece } from '../structures/Piece';\nimport type { Store, StoreLogger } from '../structures/Store';\nimport type {\n\tAsyncPreloadResult,\n\tFilterResult,\n\tHydratedModuleData,\n\tILoaderResult,\n\tILoaderResultEntry,\n\tILoaderStrategy,\n\tModuleData\n} from './ILoaderStrategy';\nimport { classExtends, isClass } from './Shared';\n\n/**\n * A multi-purpose feature-complete loader strategy supporting multi-piece modules as well as supporting both ECMAScript\n * Modules and CommonJS with reloading support.\n */\nexport class LoaderStrategy<T extends Piece> implements ILoaderStrategy<T> {\n\tpublic clientUsesESModules = getRootData().type === 'ESM';\n\tpublic supportedExtensions = ['.js', '.cjs', '.mjs'];\n\tprivate readonly filterDtsFiles: boolean = false;\n\n\tpublic constructor() {\n\t\t/**\n\t\t *\n\t\t * Under various conditions we need to support loading TypeScript files. These conditions are:\n\t\t *\n\t\t * - {@linkplain https://github.com/TypeStrong/ts-node `ts-node`} is being used.\n\t\t * - {@linkplain https://github.com/wclr/ts-node-dev `ts-node-dev`} is being used.\n\t\t * - {@linkplain https://deno.com `Deno`} is being used.\n\t\t * - {@linkplain https://bun.sh `bun`} is being used.\n\t\t *\n\t\t * Each of these packages and runtimes support loading TypeScript files directly and do not need to be compiled\n\t\t * to JavaScript first.\n\t\t */\n\t\tconst shouldLoadTsFiles =\n\t\t\tReflect.has(process, Symbol.for('ts-node.register.instance')) || // ts-node support\n\t\t\tReflect.has(globalThis, 'Deno') || // Deno support\n\t\t\t!isNullish(process.env.TS_NODE_DEV) || // ts-node-dev support\n\t\t\t'bun' in process.versions; // bun support\n\n\t\tif (shouldLoadTsFiles) {\n\t\t\tthis.supportedExtensions.push('.ts', '.cts', '.mts');\n\t\t\tthis.filterDtsFiles = true;\n\t\t}\n\t}\n\n\tpublic filter(path: string): FilterResult {\n\t\t// Retrieve the file extension.\n\t\tconst extension = extname(path);\n\t\tif (!this.supportedExtensions.includes(extension)) return null;\n\n\t\tif (this.filterDtsFiles && path.endsWith('.d.ts')) return null;\n\n\t\t// Retrieve the name of the file, return null if empty.\n\t\tconst name = basename(path, extension);\n\t\tif (name === '' || name.startsWith('_')) return null;\n\n\t\t// Return the name and extension.\n\t\treturn { extension, path, name };\n\t}\n\n\tpublic async preload(file: ModuleData): AsyncPreloadResult<T> {\n\t\tconst mjs = ['.mjs', '.mts'].includes(file.extension) || (['.js', '.ts'].includes(file.extension) && this.clientUsesESModules);\n\t\tif (mjs) {\n\t\t\tconst url = pathToFileURL(file.path);\n\t\t\turl.searchParams.append('d', Date.now().toString());\n\t\t\turl.searchParams.append('name', file.name);\n\t\t\turl.searchParams.append('extension', file.extension);\n\t\t\treturn mjsImport(url);\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-var-requires\n\t\tconst mod = require(file.path);\n\t\tdelete require.cache[require.resolve(file.path)];\n\t\treturn mod;\n\t}\n\n\tpublic async *load(store: Store<T>, file: HydratedModuleData): ILoaderResult<T> {\n\t\tlet yielded = false;\n\t\tconst result = await this.preload(file);\n\n\t\t// Support `module.exports`:\n\t\tif (isClass(result) && classExtends(result, store.Constructor)) {\n\t\t\tyield result;\n\t\t\tyielded = true;\n\t\t}\n\n\t\t// Support any other export:\n\t\tfor (const value of Object.values(result)) {\n\t\t\tif (isClass(value) && classExtends(value, store.Constructor)) {\n\t\t\t\tyield value as ILoaderResultEntry<T>;\n\t\t\t\tyielded = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!yielded) {\n\t\t\tthrow new MissingExportsError(file.path);\n\t\t}\n\t}\n\n\tpublic onLoad(store: Store<T>, piece: T): Awaitable<unknown>;\n\tpublic onLoad(): unknown {\n\t\treturn undefined;\n\t}\n\n\tpublic onLoadAll(store: Store<T>): Awaitable<unknown>;\n\tpublic onLoadAll(): unknown {\n\t\treturn undefined;\n\t}\n\n\tpublic onUnload(store: Store<T>, piece: T): Awaitable<unknown>;\n\tpublic onUnload(): unknown {\n\t\treturn undefined;\n\t}\n\n\tpublic onUnloadAll(store: Store<T>): Awaitable<unknown>;\n\tpublic onUnloadAll(): unknown {\n\t\treturn undefined;\n\t}\n\n\tpublic onError(error: Error, path: string): void {\n\t\tconsole.error(`Error when loading '${path}':`, error);\n\t}\n\n\tpublic async *walk(store: Store<T>, path: string, logger?: StoreLogger | null): AsyncIterableIterator<string> {\n\t\tlogger?.(`[STORE => ${store.name}] [WALK] Loading all pieces from '${path}'.`);\n\t\ttry {\n\t\t\tconst dir = await opendir(path);\n\t\t\tfor await (const item of dir) {\n\t\t\t\tif (item.isFile()) yield join(dir.path, item.name);\n\t\t\t\telse if (item.isDirectory()) yield* this.walk(store, join(dir.path, item.name), logger);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Specifically ignore ENOENT, which is commonly raised by fs operations\n\t\t\t// to indicate that a component of the specified pathname does not exist.\n\t\t\t// No entity (file or directory) could be found by the given path.\n\t\t\tif ((error as ErrorWithCode).code !== 'ENOENT') this.onError(error as Error, path);\n\t\t}\n\t}\n}\n\ntype ErrorWithCode = Error & { code: string };\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name } from '../../chunk-
|
|
1
|
+
import { __name } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
|
|
3
3
|
// src/lib/strategies/Shared.ts
|
|
4
4
|
function isClass(value) {
|
|
@@ -8,8 +8,7 @@ __name(isClass, "isClass");
|
|
|
8
8
|
function classExtends(value, base) {
|
|
9
9
|
let ctor = value;
|
|
10
10
|
while (ctor !== null) {
|
|
11
|
-
if (ctor === base)
|
|
12
|
-
return true;
|
|
11
|
+
if (ctor === base) return true;
|
|
13
12
|
ctor = Object.getPrototypeOf(ctor);
|
|
14
13
|
}
|
|
15
14
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/strategies/Shared.ts"],"names":[],"mappings":";;;;;AAOO,SAAS,QAAQ,OAAuC;AAC9D,SAAO,OAAO,UAAU,cAAc,OAAO,MAAM,cAAc;AAClE;AAFgB;AAUT,SAAS,aAAqC,OAAqB,MAAqB;AAC9F,MAAI,OAA4B;AAChC,SAAO,SAAS,MAAM;AACrB,QAAI,SAAS
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/strategies/Shared.ts"],"names":[],"mappings":";;;;;AAOO,SAAS,QAAQ,OAAuC;AAC9D,SAAO,OAAO,UAAU,cAAc,OAAO,MAAM,cAAc;AAClE;AAFgB;AAUT,SAAS,aAAqC,OAAqB,MAAqB;AAC9F,MAAI,OAA4B;AAChC,SAAO,SAAS,MAAM;AACrB,QAAI,SAAS,KAAM,QAAO;AAC1B,WAAO,OAAO,eAAe,IAAI;AAAA,EAClC;AAEA,SAAO;AACR;AARgB","sourcesContent":["import type { AbstractCtor } from '@sapphire/utilities';\n\n/**\n * Determines whether or not a value is a class.\n * @param value The piece to be checked.\n * @private\n */\nexport function isClass(value: unknown): value is AbstractCtor {\n\treturn typeof value === 'function' && typeof value.prototype === 'object';\n}\n\n/**\n * Checks whether or not the value class extends the base class.\n * @param value The constructor to be checked against.\n * @param base The base constructor.\n * @private\n */\nexport function classExtends<T extends AbstractCtor>(value: AbstractCtor, base: T): value is T {\n\tlet ctor: AbstractCtor | null = value;\n\twhile (ctor !== null) {\n\t\tif (ctor === base) return true;\n\t\tctor = Object.getPrototypeOf(ctor);\n\t}\n\n\treturn false;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name, __publicField } from '../../chunk-
|
|
1
|
+
import { __name, __publicField } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { Collection } from '@discordjs/collection';
|
|
3
3
|
import { Store } from './Store.mjs';
|
|
4
4
|
|
|
@@ -33,8 +33,7 @@ var _AliasStore = class _AliasStore extends Store {
|
|
|
33
33
|
const piece = this.resolve(name);
|
|
34
34
|
for (const alias of piece.aliases) {
|
|
35
35
|
const aliasPiece = this.aliases.get(alias);
|
|
36
|
-
if (aliasPiece === piece)
|
|
37
|
-
this.aliases.delete(alias);
|
|
36
|
+
if (aliasPiece === piece) this.aliases.delete(alias);
|
|
38
37
|
}
|
|
39
38
|
return super.unload(piece);
|
|
40
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/structures/AliasStore.ts"],"names":[],"mappings":";;;;;;AAAA,SAAS,kBAAkB;AAE3B,SAAS,aAAa;AAMf,IAAM,cAAN,MAAM,oBAAgG,MAAoB;AAAA,EAA1H;AAAA;AAIN;AAAA;AAAA;AAAA,wBAAgB,WAAU,IAAI,WAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpC,IAAI,KAA4B;AAC/C,WAAO,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,GAAG;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMgB,IAAI,KAAsB;AACzC,WAAO,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,GAAG;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOgB,OAAO,MAA8B;AACpD,UAAM,QAAQ,KAAK,QAAQ,IAAI;AAG/B,eAAW,SAAS,MAAM,SAAS;AAElC,YAAM,aAAa,KAAK,QAAQ,IAAI,KAAK;AACzC,UAAI,eAAe
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/structures/AliasStore.ts"],"names":[],"mappings":";;;;;;AAAA,SAAS,kBAAkB;AAE3B,SAAS,aAAa;AAMf,IAAM,cAAN,MAAM,oBAAgG,MAAoB;AAAA,EAA1H;AAAA;AAIN;AAAA;AAAA;AAAA,wBAAgB,WAAU,IAAI,WAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpC,IAAI,KAA4B;AAC/C,WAAO,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,GAAG;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMgB,IAAI,KAAsB;AACzC,WAAO,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,GAAG;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOgB,OAAO,MAA8B;AACpD,UAAM,QAAQ,KAAK,QAAQ,IAAI;AAG/B,eAAW,SAAS,MAAM,SAAS;AAElC,YAAM,aAAa,KAAK,QAAQ,IAAI,KAAK;AACzC,UAAI,eAAe,MAAO,MAAK,QAAQ,OAAO,KAAK;AAAA,IACpD;AAEA,WAAO,MAAM,OAAO,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAsB,OAAO,OAAU;AACtC,eAAW,OAAO,MAAM,SAAS;AAChC,WAAK,QAAQ,IAAI,KAAK,KAAK;AAAA,IAC5B;AAEA,WAAO,MAAM,OAAO,KAAK;AAAA,EAC1B;AACD;AApDiI;AAA1H,IAAM,aAAN","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport type { AliasPiece } from './AliasPiece';\nimport { Store } from './Store';\nimport type { StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The store class which contains {@link AliasPiece}s.\n */\nexport class AliasStore<T extends AliasPiece, StoreName extends StoreRegistryKey = StoreRegistryKey> extends Store<T, StoreName> {\n\t/**\n\t * The aliases referencing to pieces.\n\t */\n\tpublic readonly aliases = new Collection<string, T>();\n\n\t/**\n\t * Looks up the name by the store, falling back to an alias lookup.\n\t * @param key The key to look for.\n\t */\n\tpublic override get(key: string): T | undefined {\n\t\treturn super.get(key) ?? this.aliases.get(key);\n\t}\n\n\t/**\n\t * Checks whether a key is in the store, or is an alias\n\t * @param key The key to check\n\t */\n\tpublic override has(key: string): boolean {\n\t\treturn super.has(key) || this.aliases.has(key);\n\t}\n\n\t/**\n\t * Unloads a piece given its instance or its name, and removes all the aliases.\n\t * @param name The name of the file to load.\n\t * @return Returns the piece that was unloaded.\n\t */\n\tpublic override unload(name: string | T): Promise<T> {\n\t\tconst piece = this.resolve(name);\n\n\t\t// Unload all aliases for the given piece:\n\t\tfor (const alias of piece.aliases) {\n\t\t\t// We don't want to delete aliases that were overriden by another piece:\n\t\t\tconst aliasPiece = this.aliases.get(alias);\n\t\t\tif (aliasPiece === piece) this.aliases.delete(alias);\n\t\t}\n\n\t\treturn super.unload(piece);\n\t}\n\n\t/**\n\t * Inserts a piece into the store, and adds all the aliases.\n\t * @param piece The piece to be inserted into the store.\n\t * @return The inserted piece.\n\t */\n\tpublic override async insert(piece: T) {\n\t\tfor (const key of piece.aliases) {\n\t\t\tthis.aliases.set(key, piece);\n\t\t}\n\n\t\treturn super.insert(piece);\n\t}\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name, __publicField, __privateAdd, __privateSet, __privateGet } from '../../chunk-
|
|
1
|
+
import { __name, __publicField, __privateAdd, __privateSet, __privateGet } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { Collection } from '@discordjs/collection';
|
|
3
3
|
import { isClass, classExtends } from '@sapphire/utilities';
|
|
4
4
|
import { join } from 'path';
|
|
@@ -10,8 +10,8 @@ import { LoaderStrategy } from '../strategies/LoaderStrategy.mjs';
|
|
|
10
10
|
import { StoreRegistry } from './StoreRegistry.mjs';
|
|
11
11
|
|
|
12
12
|
var defaultStrategy = new LoaderStrategy();
|
|
13
|
-
var _a, _calledLoadAll, _walk;
|
|
14
|
-
var _Store = class _Store extends Collection {
|
|
13
|
+
var _a, _b, _calledLoadAll, _walk;
|
|
14
|
+
var _Store = class _Store extends (_b = Collection, _a = ManuallyRegisteredPiecesSymbol, _b) {
|
|
15
15
|
/**
|
|
16
16
|
* @param constructor The piece constructor this store loads.
|
|
17
17
|
* @param options The options for the store.
|
|
@@ -33,7 +33,7 @@ var _Store = class _Store extends Collection {
|
|
|
33
33
|
/**
|
|
34
34
|
* The walk function for the store.
|
|
35
35
|
*/
|
|
36
|
-
__privateAdd(this, _walk
|
|
36
|
+
__privateAdd(this, _walk);
|
|
37
37
|
this.Constructor = constructor;
|
|
38
38
|
this.name = options.name;
|
|
39
39
|
this.paths = new Set(options.paths ?? []);
|
|
@@ -203,12 +203,10 @@ var _Store = class _Store extends Collection {
|
|
|
203
203
|
resolve(name) {
|
|
204
204
|
if (typeof name === "string") {
|
|
205
205
|
const result = this.get(name);
|
|
206
|
-
if (typeof result === "undefined")
|
|
207
|
-
throw new LoaderError(LoaderErrorType.UnloadedPiece, `The piece '${name}' does not exist.`);
|
|
206
|
+
if (typeof result === "undefined") throw new LoaderError(LoaderErrorType.UnloadedPiece, `The piece '${name}' does not exist.`);
|
|
208
207
|
return result;
|
|
209
208
|
}
|
|
210
|
-
if (name instanceof this.Constructor)
|
|
211
|
-
return name;
|
|
209
|
+
if (name instanceof this.Constructor) return name;
|
|
212
210
|
throw new LoaderError(LoaderErrorType.IncorrectType, `The piece '${name.name}' is not an instance of '${this.Constructor.name}'.`);
|
|
213
211
|
}
|
|
214
212
|
/**
|
|
@@ -217,8 +215,7 @@ var _Store = class _Store extends Collection {
|
|
|
217
215
|
* @return The inserted piece.
|
|
218
216
|
*/
|
|
219
217
|
async insert(piece) {
|
|
220
|
-
if (!piece.enabled)
|
|
221
|
-
return piece;
|
|
218
|
+
if (!piece.enabled) return piece;
|
|
222
219
|
this.strategy.onLoad(this, piece);
|
|
223
220
|
await piece.onLoad();
|
|
224
221
|
_Store.logger?.(`[STORE => ${this.name}] [INSERT] Loaded new piece '${piece.name}'.`);
|
|
@@ -279,7 +276,6 @@ var _Store = class _Store extends Collection {
|
|
|
279
276
|
}
|
|
280
277
|
}
|
|
281
278
|
};
|
|
282
|
-
_a = ManuallyRegisteredPiecesSymbol;
|
|
283
279
|
_calledLoadAll = new WeakMap();
|
|
284
280
|
_walk = new WeakMap();
|
|
285
281
|
__name(_Store, "Store");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/structures/Store.ts"],"names":["Store"],"mappings":"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","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport { classExtends, isClass, type AbstractConstructor, type Constructor } from '@sapphire/utilities';\nimport { join } from 'path';\nimport { LoaderError, LoaderErrorType } from '../errors/LoaderError';\nimport { resolvePath, type Path } from '../internal/Path';\nimport { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constants';\nimport { container, type Container } from '../shared/Container';\nimport type { HydratedModuleData, ILoaderResultEntry, ILoaderStrategy, ModuleData } from '../strategies/ILoaderStrategy';\nimport { LoaderStrategy } from '../strategies/LoaderStrategy';\nimport type { Piece } from './Piece';\nimport { StoreRegistry, type StoreRegistryEntries, type StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The options for the store, this features both hooks (changes the behaviour) and handlers (similar to event listeners).\n */\nexport interface StoreOptions<T extends Piece, StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The name for this store.\n\t */\n\treadonly name: StoreName;\n\n\t/**\n\t * The paths to load pieces from, should be absolute.\n\t * @default []\n\t */\n\treadonly paths?: readonly string[];\n\n\t/**\n\t * The strategy to be used for the loader.\n\t * @default Store.defaultStrategy\n\t */\n\treadonly strategy?: ILoaderStrategy<T>;\n}\n\n/**\n * An interface representing a logger function.\n */\nexport interface StoreLogger {\n\t/**\n\t * @param value The string to print. All strings will be formatted with the format `[STORE => ${name}] [${type}] ${content}`,\n\t * where the content may have identifiers (values or names of methods) surrounded by `'`. For example:\n\t *\n\t * - `[STORE => commands] [LOAD] Skipped piece '/home/user/bot/src/commands/foo.js' as 'LoaderStrategy#filter' returned 'null'.`\n\t * - `[STORE => commands] [INSERT] Unloaded new piece 'foo' due to 'enabled' being 'false'.`\n\t * - `[STORE => commands] [UNLOAD] Unloaded piece 'foo'.`\n\t */\n\t(value: string): void;\n}\n\nconst defaultStrategy = new LoaderStrategy();\n\n/**\n * The store class which contains {@link Piece}s.\n */\nexport class Store<T extends Piece, StoreName extends StoreRegistryKey = StoreRegistryKey> extends Collection<string, T> {\n\tpublic readonly Constructor: AbstractConstructor<T>;\n\tpublic readonly name: StoreName;\n\tpublic readonly paths: Set<string>;\n\tpublic readonly strategy: ILoaderStrategy<T>;\n\n\t/**\n\t * The queue of manually registered pieces to load.\n\t */\n\tprivate readonly [ManuallyRegisteredPiecesSymbol] = new Map<string, StoreManuallyRegisteredPiece<StoreName>>();\n\n\t/**\n\t * Whether or not the store has called `loadAll` at least once.\n\t */\n\t#calledLoadAll = false;\n\n\t/**\n\t * The walk function for the store.\n\t */\n\t#walk: LoaderStrategy<T>['walk'];\n\n\t/**\n\t * @param constructor The piece constructor this store loads.\n\t * @param options The options for the store.\n\t */\n\tpublic constructor(constructor: AbstractConstructor<T>, options: StoreOptions<T, StoreName>) {\n\t\tsuper();\n\t\tthis.Constructor = constructor;\n\t\tthis.name = options.name as StoreRegistryKey;\n\t\tthis.paths = new Set(options.paths ?? []);\n\t\tthis.strategy = options.strategy ?? Store.defaultStrategy;\n\n\t\tthis.#walk =\n\t\t\ttypeof this.strategy.walk === 'function' //\n\t\t\t\t? this.strategy.walk.bind(this.strategy)\n\t\t\t\t: defaultStrategy.walk.bind(defaultStrategy);\n\t}\n\n\t/**\n\t * A reference to the {@link Container} object for ease of use.\n\t * @see container\n\t */\n\tpublic get container(): Container {\n\t\treturn container;\n\t}\n\n\t/**\n\t * Registers a directory into the store.\n\t * @param path The path to be added.\n\t * @example\n\t * ```typescript\n\t * store\n\t * .registerPath(resolve('commands'))\n\t * .registerPath(resolve('third-party', 'commands'));\n\t * ```\n\t */\n\tpublic registerPath(path: Path): this {\n\t\tconst root = resolvePath(path);\n\n\t\tthis.paths.add(root);\n\t\tStore.logger?.(`[STORE => ${this.name}] [REGISTER] Registered path '${root}'.`);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a piece into the store's list of manually registered pieces. If {@linkcode Store.loadAll()} was called, the\n\t * piece will be loaded immediately, otherwise it will be queued until {@linkcode Store.loadAll()} is called.\n\t *\n\t * All manually registered pieces will be kept even after they are loaded to ensure they can be loaded again if\n\t * {@linkcode Store.loadAll()} is called again.\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 always throw a {@link TypeError} if `entry.piece` is not a class.\n\t * - This method will always throw a {@linkcode LoaderError} if the piece does not extend the\n\t * {@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 StoreRegistry.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.get('commands').loadPiece({\n\t * name: 'ping',\n\t * piece: PingCommand\n\t * });\n\t * ```\n\t */\n\tpublic async loadPiece(entry: StoreManuallyRegisteredPiece<StoreName>) {\n\t\tif (!isClass(entry.piece)) {\n\t\t\tthrow new TypeError(`The piece ${entry.name} is not a Class. ${String(entry.piece)}`);\n\t\t}\n\n\t\t// If the piece does not extend the store's Piece class, throw an error:\n\t\tif (!classExtends(entry.piece, this.Constructor as Constructor<T>)) {\n\t\t\tthrow new LoaderError(LoaderErrorType.IncorrectType, `The piece ${entry.name} does not extend ${this.name}`);\n\t\t}\n\n\t\tthis[ManuallyRegisteredPiecesSymbol].set(entry.name, entry);\n\t\tif (this.#calledLoadAll) {\n\t\t\tconst piece = this.construct(entry.piece as unknown as Constructor<T>, {\n\t\t\t\tname: entry.name,\n\t\t\t\troot: VirtualPath,\n\t\t\t\tpath: VirtualPath,\n\t\t\t\textension: VirtualPath\n\t\t\t});\n\t\t\tawait this.insert(piece);\n\t\t}\n\t}\n\n\t/**\n\t * Loads one or more pieces from a path.\n\t * @param root The root directory the file is from.\n\t * @param path The path of the file to load, relative to the `root`.\n\t * @return All the loaded pieces.\n\t */\n\tpublic async load(root: string, path: string): Promise<T[]> {\n\t\tif (root === VirtualPath) {\n\t\t\tthrow new LoaderError(LoaderErrorType.VirtualPiece, `Cannot load a virtual file.`);\n\t\t}\n\n\t\tconst full = join(root, path);\n\t\tconst data = this.strategy.filter(full);\n\t\tif (data === null) {\n\t\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD] Skipped piece '${full}' as 'LoaderStrategy#filter' returned 'null'.`);\n\t\t\treturn [];\n\t\t}\n\n\t\tconst promises: Promise<T>[] = [];\n\t\tconst finishedData = this.hydrateModuleData(root, data);\n\t\tfor await (const Ctor of this.strategy.load(this, finishedData)) {\n\t\t\tpromises.push(this.insert(this.construct(Ctor, finishedData)));\n\t\t}\n\n\t\treturn Promise.all(promises);\n\t}\n\n\t/**\n\t * Unloads a piece given its instance or its name.\n\t * @param name The name of the file to load.\n\t * @return Returns the piece that was unloaded.\n\t */\n\tpublic async unload(name: string | T): Promise<T> {\n\t\tconst piece = this.resolve(name);\n\n\t\t// Unload piece:\n\t\tthis.strategy.onUnload(this, piece);\n\t\tawait piece.onUnload();\n\t\tStore.logger?.(`[STORE => ${this.name}] [UNLOAD] Unloaded piece '${piece.name}'.`);\n\n\t\t// Remove from cache and return it:\n\t\tthis.delete(piece.name);\n\t\tStore.logger?.(`[STORE => ${this.name}] [UNLOAD] Removed piece '${piece.name}'.`);\n\t\treturn piece;\n\t}\n\n\t/**\n\t * Unloads all pieces from the store.\n\t */\n\tpublic async unloadAll(): Promise<T[]> {\n\t\tconst promises: Promise<T>[] = [];\n\t\tfor (const piece of this.values()) {\n\t\t\tpromises.push(this.unload(piece));\n\t\t}\n\n\t\tconst results = await Promise.all(promises);\n\n\t\tthis.strategy.onUnloadAll(this);\n\t\tStore.logger?.(`[STORE => ${this.name}] [UNLOAD-ALL] Removed all pieces.`);\n\t\treturn results;\n\t}\n\n\t/**\n\t * Loads all pieces from all directories specified by {@link paths}.\n\t */\n\tpublic async loadAll(): Promise<void> {\n\t\tthis.#calledLoadAll = true;\n\n\t\tconst pieces: T[] = [];\n\t\tfor (const entry of this[ManuallyRegisteredPiecesSymbol].values()) {\n\t\t\tconst piece = this.construct(entry.piece as unknown as Constructor<T>, {\n\t\t\t\tname: entry.name,\n\t\t\t\troot: VirtualPath,\n\t\t\t\tpath: VirtualPath,\n\t\t\t\textension: VirtualPath\n\t\t\t});\n\t\t\tpieces.push(piece);\n\t\t}\n\n\t\tfor (const path of this.paths) {\n\t\t\tfor await (const piece of this.loadPath(path)) {\n\t\t\t\tpieces.push(piece);\n\t\t\t}\n\t\t}\n\n\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD-ALL] Found '${pieces.length}' pieces.`);\n\n\t\t// Clear the store before inserting the new pieces:\n\t\tawait this.unloadAll();\n\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD-ALL] Cleared all pieces.`);\n\n\t\t// Load each piece:\n\t\tfor (const piece of pieces) {\n\t\t\tawait this.insert(piece);\n\t\t}\n\n\t\t// Call onLoadAll:\n\t\tthis.strategy.onLoadAll(this);\n\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD-ALL] Successfully loaded '${this.size}' pieces.`);\n\t}\n\n\t/**\n\t * Resolves a piece by its name or its instance.\n\t * @param name The name of the piece or the instance itself.\n\t * @return The resolved piece.\n\t */\n\tpublic resolve(name: string | T): T {\n\t\tif (typeof name === 'string') {\n\t\t\tconst result = this.get(name);\n\t\t\tif (typeof result === 'undefined') throw new LoaderError(LoaderErrorType.UnloadedPiece, `The piece '${name}' does not exist.`);\n\t\t\treturn result;\n\t\t}\n\n\t\tif (name instanceof this.Constructor) return name;\n\t\tthrow new LoaderError(LoaderErrorType.IncorrectType, `The piece '${name.name}' is not an instance of '${this.Constructor.name}'.`);\n\t}\n\n\t/**\n\t * Inserts a piece into the store.\n\t * @param piece The piece to be inserted into the store.\n\t * @return The inserted piece.\n\t */\n\tpublic async insert(piece: T): Promise<T> {\n\t\tif (!piece.enabled) return piece;\n\n\t\t// Load piece:\n\t\tthis.strategy.onLoad(this, piece);\n\t\tawait piece.onLoad();\n\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Loaded new piece '${piece.name}'.`);\n\n\t\t// If the onLoad disabled the piece, call unload and return it:\n\t\tif (!piece.enabled) {\n\t\t\t// Unload piece:\n\t\t\tthis.strategy.onUnload(this, piece);\n\t\t\tawait piece.onUnload();\n\t\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Unloaded new piece '${piece.name}' due to 'enabled' being 'false'.`);\n\n\t\t\treturn piece;\n\t\t}\n\n\t\t// Unload existing piece, if any:\n\t\tconst previous = super.get(piece.name);\n\t\tif (previous) {\n\t\t\tawait this.unload(previous);\n\t\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Unloaded existing piece '${piece.name}' due to conflicting 'name'.`);\n\t\t}\n\n\t\t// Set the new piece and return it:\n\t\tthis.set(piece.name, piece);\n\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Inserted new piece '${piece.name}'.`);\n\t\treturn piece;\n\t}\n\n\t/**\n\t * Constructs a {@link Piece} instance.\n\t * @param Ctor The {@link Piece}'s constructor used to build the instance.\n\t * @param data The module's information\n\t * @return An instance of the constructed piece.\n\t */\n\tpublic construct(Ctor: ILoaderResultEntry<T>, data: HydratedModuleData): T {\n\t\treturn new Ctor({ store: this, root: data.root, path: data.path, name: data.name }, { name: data.name, enabled: true });\n\t}\n\n\t/**\n\t * Adds the final module data properties.\n\t * @param root The root directory to add.\n\t * @param data The module data returned from {@link ILoaderStrategy.filter}.\n\t * @returns The finished module data.\n\t */\n\tprivate hydrateModuleData(root: string, data: ModuleData): HydratedModuleData {\n\t\treturn { root, ...data };\n\t}\n\n\t/**\n\t * Loads a directory into the store.\n\t * @param root The directory to load the pieces from.\n\t * @return An async iterator that yields the pieces to be loaded into the store.\n\t */\n\tprivate async *loadPath(root: string): AsyncIterableIterator<T> {\n\t\tStore.logger?.(`[STORE => ${this.name}] [WALK] Loading all pieces from '${root}'.`);\n\t\tfor await (const child of this.#walk(this, root, Store.logger)) {\n\t\t\tconst data = this.strategy.filter(child);\n\t\t\tif (data === null) {\n\t\t\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD] Skipped piece '${child}' as 'LoaderStrategy#filter' returned 'null'.`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst finishedData = this.hydrateModuleData(root, data);\n\t\t\t\tfor await (const Ctor of this.strategy.load(this, finishedData)) {\n\t\t\t\t\tyield this.construct(Ctor, finishedData);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.strategy.onError(error as Error, data.path);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The default strategy, defaults to {@link LoaderStrategy}, which is constructed on demand when a store is constructed,\n\t * when none was set beforehand.\n\t */\n\tpublic static defaultStrategy: ILoaderStrategy<any> = defaultStrategy;\n\n\t/**\n\t * The default logger, defaults to `null`.\n\t */\n\tpublic static logger: StoreLogger | null = null;\n}\n\n/**\n * An entry for a manually registered piece using {@linkcode Store.loadPiece()}.\n * @since 3.8.0\n */\nexport interface StoreManuallyRegisteredPiece<StoreName extends StoreRegistryKey> {\n\tname: string;\n\tpiece: StoreRegistryEntries[StoreName] extends Store<infer Piece> ? Constructor<Piece> : never;\n}\n\nexport namespace Store {\n\texport const Registry = StoreRegistry;\n\texport type Options<T extends Piece> = StoreOptions<T>;\n\texport type Logger = StoreLogger;\n\texport type RegistryEntries = StoreRegistryEntries;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/structures/Store.ts"],"names":["Store"],"mappings":"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","sourcesContent":["import { Collection } from '@discordjs/collection';\nimport { classExtends, isClass, type AbstractConstructor, type Constructor } from '@sapphire/utilities';\nimport { join } from 'path';\nimport { LoaderError, LoaderErrorType } from '../errors/LoaderError';\nimport { resolvePath, type Path } from '../internal/Path';\nimport { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constants';\nimport { container, type Container } from '../shared/Container';\nimport type { HydratedModuleData, ILoaderResultEntry, ILoaderStrategy, ModuleData } from '../strategies/ILoaderStrategy';\nimport { LoaderStrategy } from '../strategies/LoaderStrategy';\nimport type { Piece } from './Piece';\nimport { StoreRegistry, type StoreRegistryEntries, type StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The options for the store, this features both hooks (changes the behaviour) and handlers (similar to event listeners).\n */\nexport interface StoreOptions<T extends Piece, StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The name for this store.\n\t */\n\treadonly name: StoreName;\n\n\t/**\n\t * The paths to load pieces from, should be absolute.\n\t * @default []\n\t */\n\treadonly paths?: readonly string[];\n\n\t/**\n\t * The strategy to be used for the loader.\n\t * @default Store.defaultStrategy\n\t */\n\treadonly strategy?: ILoaderStrategy<T>;\n}\n\n/**\n * An interface representing a logger function.\n */\nexport interface StoreLogger {\n\t/**\n\t * @param value The string to print. All strings will be formatted with the format `[STORE => ${name}] [${type}] ${content}`,\n\t * where the content may have identifiers (values or names of methods) surrounded by `'`. For example:\n\t *\n\t * - `[STORE => commands] [LOAD] Skipped piece '/home/user/bot/src/commands/foo.js' as 'LoaderStrategy#filter' returned 'null'.`\n\t * - `[STORE => commands] [INSERT] Unloaded new piece 'foo' due to 'enabled' being 'false'.`\n\t * - `[STORE => commands] [UNLOAD] Unloaded piece 'foo'.`\n\t */\n\t(value: string): void;\n}\n\nconst defaultStrategy = new LoaderStrategy();\n\n/**\n * The store class which contains {@link Piece}s.\n */\nexport class Store<T extends Piece, StoreName extends StoreRegistryKey = StoreRegistryKey> extends Collection<string, T> {\n\tpublic readonly Constructor: AbstractConstructor<T>;\n\tpublic readonly name: StoreName;\n\tpublic readonly paths: Set<string>;\n\tpublic readonly strategy: ILoaderStrategy<T>;\n\n\t/**\n\t * The queue of manually registered pieces to load.\n\t */\n\tprivate readonly [ManuallyRegisteredPiecesSymbol] = new Map<string, StoreManuallyRegisteredPiece<StoreName>>();\n\n\t/**\n\t * Whether or not the store has called `loadAll` at least once.\n\t */\n\t#calledLoadAll = false;\n\n\t/**\n\t * The walk function for the store.\n\t */\n\t#walk: LoaderStrategy<T>['walk'];\n\n\t/**\n\t * @param constructor The piece constructor this store loads.\n\t * @param options The options for the store.\n\t */\n\tpublic constructor(constructor: AbstractConstructor<T>, options: StoreOptions<T, StoreName>) {\n\t\tsuper();\n\t\tthis.Constructor = constructor;\n\t\tthis.name = options.name as StoreRegistryKey;\n\t\tthis.paths = new Set(options.paths ?? []);\n\t\tthis.strategy = options.strategy ?? Store.defaultStrategy;\n\n\t\tthis.#walk =\n\t\t\ttypeof this.strategy.walk === 'function' //\n\t\t\t\t? this.strategy.walk.bind(this.strategy)\n\t\t\t\t: defaultStrategy.walk.bind(defaultStrategy);\n\t}\n\n\t/**\n\t * A reference to the {@link Container} object for ease of use.\n\t * @see container\n\t */\n\tpublic get container(): Container {\n\t\treturn container;\n\t}\n\n\t/**\n\t * Registers a directory into the store.\n\t * @param path The path to be added.\n\t * @example\n\t * ```typescript\n\t * store\n\t * .registerPath(resolve('commands'))\n\t * .registerPath(resolve('third-party', 'commands'));\n\t * ```\n\t */\n\tpublic registerPath(path: Path): this {\n\t\tconst root = resolvePath(path);\n\n\t\tthis.paths.add(root);\n\t\tStore.logger?.(`[STORE => ${this.name}] [REGISTER] Registered path '${root}'.`);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a piece into the store's list of manually registered pieces. If {@linkcode Store.loadAll()} was called, the\n\t * piece will be loaded immediately, otherwise it will be queued until {@linkcode Store.loadAll()} is called.\n\t *\n\t * All manually registered pieces will be kept even after they are loaded to ensure they can be loaded again if\n\t * {@linkcode Store.loadAll()} is called again.\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 always throw a {@link TypeError} if `entry.piece` is not a class.\n\t * - This method will always throw a {@linkcode LoaderError} if the piece does not extend the\n\t * {@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 StoreRegistry.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.get('commands').loadPiece({\n\t * name: 'ping',\n\t * piece: PingCommand\n\t * });\n\t * ```\n\t */\n\tpublic async loadPiece(entry: StoreManuallyRegisteredPiece<StoreName>) {\n\t\tif (!isClass(entry.piece)) {\n\t\t\tthrow new TypeError(`The piece ${entry.name} is not a Class. ${String(entry.piece)}`);\n\t\t}\n\n\t\t// If the piece does not extend the store's Piece class, throw an error:\n\t\tif (!classExtends(entry.piece, this.Constructor as Constructor<T>)) {\n\t\t\tthrow new LoaderError(LoaderErrorType.IncorrectType, `The piece ${entry.name} does not extend ${this.name}`);\n\t\t}\n\n\t\tthis[ManuallyRegisteredPiecesSymbol].set(entry.name, entry);\n\t\tif (this.#calledLoadAll) {\n\t\t\tconst piece = this.construct(entry.piece as unknown as Constructor<T>, {\n\t\t\t\tname: entry.name,\n\t\t\t\troot: VirtualPath,\n\t\t\t\tpath: VirtualPath,\n\t\t\t\textension: VirtualPath\n\t\t\t});\n\t\t\tawait this.insert(piece);\n\t\t}\n\t}\n\n\t/**\n\t * Loads one or more pieces from a path.\n\t * @param root The root directory the file is from.\n\t * @param path The path of the file to load, relative to the `root`.\n\t * @return All the loaded pieces.\n\t */\n\tpublic async load(root: string, path: string): Promise<T[]> {\n\t\tif (root === VirtualPath) {\n\t\t\tthrow new LoaderError(LoaderErrorType.VirtualPiece, `Cannot load a virtual file.`);\n\t\t}\n\n\t\tconst full = join(root, path);\n\t\tconst data = this.strategy.filter(full);\n\t\tif (data === null) {\n\t\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD] Skipped piece '${full}' as 'LoaderStrategy#filter' returned 'null'.`);\n\t\t\treturn [];\n\t\t}\n\n\t\tconst promises: Promise<T>[] = [];\n\t\tconst finishedData = this.hydrateModuleData(root, data);\n\t\tfor await (const Ctor of this.strategy.load(this, finishedData)) {\n\t\t\tpromises.push(this.insert(this.construct(Ctor, finishedData)));\n\t\t}\n\n\t\treturn Promise.all(promises);\n\t}\n\n\t/**\n\t * Unloads a piece given its instance or its name.\n\t * @param name The name of the file to load.\n\t * @return Returns the piece that was unloaded.\n\t */\n\tpublic async unload(name: string | T): Promise<T> {\n\t\tconst piece = this.resolve(name);\n\n\t\t// Unload piece:\n\t\tthis.strategy.onUnload(this, piece);\n\t\tawait piece.onUnload();\n\t\tStore.logger?.(`[STORE => ${this.name}] [UNLOAD] Unloaded piece '${piece.name}'.`);\n\n\t\t// Remove from cache and return it:\n\t\tthis.delete(piece.name);\n\t\tStore.logger?.(`[STORE => ${this.name}] [UNLOAD] Removed piece '${piece.name}'.`);\n\t\treturn piece;\n\t}\n\n\t/**\n\t * Unloads all pieces from the store.\n\t */\n\tpublic async unloadAll(): Promise<T[]> {\n\t\tconst promises: Promise<T>[] = [];\n\t\tfor (const piece of this.values()) {\n\t\t\tpromises.push(this.unload(piece));\n\t\t}\n\n\t\tconst results = await Promise.all(promises);\n\n\t\tthis.strategy.onUnloadAll(this);\n\t\tStore.logger?.(`[STORE => ${this.name}] [UNLOAD-ALL] Removed all pieces.`);\n\t\treturn results;\n\t}\n\n\t/**\n\t * Loads all pieces from all directories specified by {@link paths}.\n\t */\n\tpublic async loadAll(): Promise<void> {\n\t\tthis.#calledLoadAll = true;\n\n\t\tconst pieces: T[] = [];\n\t\tfor (const entry of this[ManuallyRegisteredPiecesSymbol].values()) {\n\t\t\tconst piece = this.construct(entry.piece as unknown as Constructor<T>, {\n\t\t\t\tname: entry.name,\n\t\t\t\troot: VirtualPath,\n\t\t\t\tpath: VirtualPath,\n\t\t\t\textension: VirtualPath\n\t\t\t});\n\t\t\tpieces.push(piece);\n\t\t}\n\n\t\tfor (const path of this.paths) {\n\t\t\tfor await (const piece of this.loadPath(path)) {\n\t\t\t\tpieces.push(piece);\n\t\t\t}\n\t\t}\n\n\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD-ALL] Found '${pieces.length}' pieces.`);\n\n\t\t// Clear the store before inserting the new pieces:\n\t\tawait this.unloadAll();\n\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD-ALL] Cleared all pieces.`);\n\n\t\t// Load each piece:\n\t\tfor (const piece of pieces) {\n\t\t\tawait this.insert(piece);\n\t\t}\n\n\t\t// Call onLoadAll:\n\t\tthis.strategy.onLoadAll(this);\n\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD-ALL] Successfully loaded '${this.size}' pieces.`);\n\t}\n\n\t/**\n\t * Resolves a piece by its name or its instance.\n\t * @param name The name of the piece or the instance itself.\n\t * @return The resolved piece.\n\t */\n\tpublic resolve(name: string | T): T {\n\t\tif (typeof name === 'string') {\n\t\t\tconst result = this.get(name);\n\t\t\tif (typeof result === 'undefined') throw new LoaderError(LoaderErrorType.UnloadedPiece, `The piece '${name}' does not exist.`);\n\t\t\treturn result;\n\t\t}\n\n\t\tif (name instanceof this.Constructor) return name;\n\t\tthrow new LoaderError(LoaderErrorType.IncorrectType, `The piece '${name.name}' is not an instance of '${this.Constructor.name}'.`);\n\t}\n\n\t/**\n\t * Inserts a piece into the store.\n\t * @param piece The piece to be inserted into the store.\n\t * @return The inserted piece.\n\t */\n\tpublic async insert(piece: T): Promise<T> {\n\t\tif (!piece.enabled) return piece;\n\n\t\t// Load piece:\n\t\tthis.strategy.onLoad(this, piece);\n\t\tawait piece.onLoad();\n\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Loaded new piece '${piece.name}'.`);\n\n\t\t// If the onLoad disabled the piece, call unload and return it:\n\t\tif (!piece.enabled) {\n\t\t\t// Unload piece:\n\t\t\tthis.strategy.onUnload(this, piece);\n\t\t\tawait piece.onUnload();\n\t\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Unloaded new piece '${piece.name}' due to 'enabled' being 'false'.`);\n\n\t\t\treturn piece;\n\t\t}\n\n\t\t// Unload existing piece, if any:\n\t\tconst previous = super.get(piece.name);\n\t\tif (previous) {\n\t\t\tawait this.unload(previous);\n\t\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Unloaded existing piece '${piece.name}' due to conflicting 'name'.`);\n\t\t}\n\n\t\t// Set the new piece and return it:\n\t\tthis.set(piece.name, piece);\n\t\tStore.logger?.(`[STORE => ${this.name}] [INSERT] Inserted new piece '${piece.name}'.`);\n\t\treturn piece;\n\t}\n\n\t/**\n\t * Constructs a {@link Piece} instance.\n\t * @param Ctor The {@link Piece}'s constructor used to build the instance.\n\t * @param data The module's information\n\t * @return An instance of the constructed piece.\n\t */\n\tpublic construct(Ctor: ILoaderResultEntry<T>, data: HydratedModuleData): T {\n\t\treturn new Ctor({ store: this, root: data.root, path: data.path, name: data.name }, { name: data.name, enabled: true });\n\t}\n\n\t/**\n\t * Adds the final module data properties.\n\t * @param root The root directory to add.\n\t * @param data The module data returned from {@link ILoaderStrategy.filter}.\n\t * @returns The finished module data.\n\t */\n\tprivate hydrateModuleData(root: string, data: ModuleData): HydratedModuleData {\n\t\treturn { root, ...data };\n\t}\n\n\t/**\n\t * Loads a directory into the store.\n\t * @param root The directory to load the pieces from.\n\t * @return An async iterator that yields the pieces to be loaded into the store.\n\t */\n\tprivate async *loadPath(root: string): AsyncIterableIterator<T> {\n\t\tStore.logger?.(`[STORE => ${this.name}] [WALK] Loading all pieces from '${root}'.`);\n\t\tfor await (const child of this.#walk(this, root, Store.logger)) {\n\t\t\tconst data = this.strategy.filter(child);\n\t\t\tif (data === null) {\n\t\t\t\tStore.logger?.(`[STORE => ${this.name}] [LOAD] Skipped piece '${child}' as 'LoaderStrategy#filter' returned 'null'.`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst finishedData = this.hydrateModuleData(root, data);\n\t\t\t\tfor await (const Ctor of this.strategy.load(this, finishedData)) {\n\t\t\t\t\tyield this.construct(Ctor, finishedData);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.strategy.onError(error as Error, data.path);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The default strategy, defaults to {@link LoaderStrategy}, which is constructed on demand when a store is constructed,\n\t * when none was set beforehand.\n\t */\n\tpublic static defaultStrategy: ILoaderStrategy<any> = defaultStrategy;\n\n\t/**\n\t * The default logger, defaults to `null`.\n\t */\n\tpublic static logger: StoreLogger | null = null;\n}\n\n/**\n * An entry for a manually registered piece using {@linkcode Store.loadPiece()}.\n * @since 3.8.0\n */\nexport interface StoreManuallyRegisteredPiece<StoreName extends StoreRegistryKey> {\n\tname: string;\n\tpiece: StoreRegistryEntries[StoreName] extends Store<infer Piece> ? Constructor<Piece> : never;\n}\n\nexport namespace Store {\n\texport const Registry = StoreRegistry;\n\texport type Options<T extends Piece> = StoreOptions<T>;\n\texport type Logger = StoreLogger;\n\texport type RegistryEntries = StoreRegistryEntries;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __name, __privateAdd, __privateGet } from '../../chunk-
|
|
1
|
+
import { __name, __privateAdd, __privateGet } from '../../chunk-KFLDEQ5J.mjs';
|
|
2
2
|
import { Collection } from '@discordjs/collection';
|
|
3
3
|
import { isClass } from '@sapphire/utilities';
|
|
4
4
|
import { join } from 'path';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sapphire/pieces",
|
|
3
|
-
"version": "4.2.3-next.
|
|
3
|
+
"version": "4.2.3-next.567c7f4",
|
|
4
4
|
"description": "Sapphire's piece loader.",
|
|
5
5
|
"main": "dist/cjs/index.cjs",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -35,34 +35,34 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@discordjs/collection": "^1.5.3",
|
|
38
|
-
"@sapphire/utilities": "^3.
|
|
39
|
-
"tslib": "^2.6.
|
|
38
|
+
"@sapphire/utilities": "^3.16.2",
|
|
39
|
+
"tslib": "^2.6.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@commitlint/cli": "^19.3.0",
|
|
43
43
|
"@commitlint/config-conventional": "^19.2.2",
|
|
44
|
-
"@favware/cliff-jumper": "^
|
|
44
|
+
"@favware/cliff-jumper": "^4.0.2",
|
|
45
45
|
"@favware/npm-deprecate": "^1.0.7",
|
|
46
46
|
"@favware/rollup-type-bundler": "^3.3.0",
|
|
47
|
-
"@sapphire/eslint-config": "^5.0.
|
|
47
|
+
"@sapphire/eslint-config": "^5.0.5",
|
|
48
48
|
"@sapphire/prettier-config": "^2.0.0",
|
|
49
49
|
"@sapphire/ts-config": "^5.0.1",
|
|
50
|
-
"@types/node": "^20.
|
|
51
|
-
"@typescript-eslint/eslint-plugin": "^7.
|
|
52
|
-
"@typescript-eslint/parser": "^7.
|
|
50
|
+
"@types/node": "^20.14.8",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^7.13.1",
|
|
52
|
+
"@typescript-eslint/parser": "^7.13.1",
|
|
53
53
|
"concurrently": "^8.2.2",
|
|
54
54
|
"cz-conventional-changelog": "^3.3.0",
|
|
55
|
-
"esbuild-plugin-file-path-extensions": "^2.
|
|
55
|
+
"esbuild-plugin-file-path-extensions": "^2.1.2",
|
|
56
56
|
"eslint": "^8.57.0",
|
|
57
57
|
"eslint-config-prettier": "^9.1.0",
|
|
58
58
|
"eslint-plugin-prettier": "^5.1.3",
|
|
59
|
-
"lint-staged": "^15.2.
|
|
60
|
-
"prettier": "^3.2
|
|
61
|
-
"rimraf": "^5.0.
|
|
62
|
-
"tsup": "^8.0
|
|
63
|
-
"typedoc": "^0.
|
|
59
|
+
"lint-staged": "^15.2.7",
|
|
60
|
+
"prettier": "^3.3.2",
|
|
61
|
+
"rimraf": "^5.0.7",
|
|
62
|
+
"tsup": "^8.1.0",
|
|
63
|
+
"typedoc": "^0.26.1",
|
|
64
64
|
"typedoc-json-parser": "^10.0.0",
|
|
65
|
-
"typescript": "^5.
|
|
65
|
+
"typescript": "^5.5.2",
|
|
66
66
|
"vitest": "^1.6.0"
|
|
67
67
|
},
|
|
68
68
|
"repository": {
|
|
@@ -107,10 +107,10 @@
|
|
|
107
107
|
"access": "public"
|
|
108
108
|
},
|
|
109
109
|
"resolutions": {
|
|
110
|
-
"acorn": "^8.
|
|
110
|
+
"acorn": "^8.12.0",
|
|
111
111
|
"ansi-regex": "^5.0.1",
|
|
112
112
|
"minimist": "^1.2.8"
|
|
113
113
|
},
|
|
114
114
|
"prettier": "@sapphire/prettier-config",
|
|
115
|
-
"packageManager": "yarn@4.
|
|
115
|
+
"packageManager": "yarn@4.3.1"
|
|
116
116
|
}
|