@sapphire/pieces 4.3.2-next.7ea1702 → 4.3.2-next.901b3bd

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.
@@ -1,5 +1,5 @@
1
1
  import { Collection } from '@discordjs/collection';
2
- import { Awaitable, Constructor, Ctor, AbstractConstructor } from '@sapphire/utilities';
2
+ import { AbstractConstructor, Awaitable, Constructor, Ctor } from '@sapphire/utilities';
3
3
 
4
4
  declare enum LoaderErrorType {
5
5
  EmptyModule = "EMPTY_MODULE",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/strategies/LoaderStrategy.ts"],"names":["getRootData","CanLoadTypeScriptFiles","path","extname","basename","url","pathToFileURL","mjsImport","isClass","classExtends","MissingExportsError","opendir","join"],"mappings":"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","file":"LoaderStrategy.cjs","sourcesContent":["import { 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';\nimport { CanLoadTypeScriptFiles } from './env';\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\tif (CanLoadTypeScriptFiles) {\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
+ {"version":3,"sources":["../../../../src/lib/strategies/LoaderStrategy.ts"],"names":["getRootData","CanLoadTypeScriptFiles","path","extname","basename","url","pathToFileURL","mjsImport","isClass","classExtends","MissingExportsError","opendir","join"],"mappings":"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","file":"LoaderStrategy.cjs","sourcesContent":["import { 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';\nimport { CanLoadTypeScriptFiles } from './env';\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\tif (CanLoadTypeScriptFiles) {\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 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/Piece.ts"],"names":["PieceLocation","container","Piece"],"mappings":";;;;;;;;;AAuDO,IAAM,MAAA,GAAN,MAAM,MAA0G,CAAA;AAAA,EA0B/G,WAAY,CAAA,OAAA,EAAyC,OAAwB,GAAA,EAAI,EAAA;AAtBxF;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAO,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAKP;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAGf,IAAA,IAAA,CAAK,QAAQ,OAAQ,CAAA,KAAA;AACrB,IAAA,IAAA,CAAK,WAAW,IAAIA,+BAAA,CAAc,OAAQ,CAAA,IAAA,EAAM,QAAQ,IAAI,CAAA;AAC5D,IAAK,IAAA,CAAA,IAAA,GAAO,OAAQ,CAAA,IAAA,IAAQ,OAAQ,CAAA,IAAA;AACpC,IAAK,IAAA,CAAA,OAAA,GAAU,QAAQ,OAAW,IAAA,IAAA;AAClC,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AAAA;AAChB;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAuB,GAAA;AACjC,IAAO,OAAAC,uBAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,MAA6B,GAAA;AACnC,IAAO,OAAA,KAAA,CAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,QAA+B,GAAA;AACrC,IAAO,OAAA,KAAA,CAAA;AAAA;AACR;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAA,MAAM,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA,IAAA,CAAK,IAAI,CAAA;AACjC,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA;AAAA;AAChB;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAM,MAAA,IAAA,CAAK,MAAM,IAAK,CAAA,IAAA,CAAK,SAAS,IAAM,EAAA,IAAA,CAAK,SAAS,QAAQ,CAAA;AAAA;AACjE;AAAA;AAAA;AAAA,EAKO,MAAoB,GAAA;AAC1B,IAAO,OAAA;AAAA,MACN,QAAA,EAAU,IAAK,CAAA,QAAA,CAAS,MAAO,EAAA;AAAA,MAC/B,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,SAAS,IAAK,CAAA,OAAA;AAAA,MACd,SAAS,IAAK,CAAA;AAAA,KACf;AAAA;AAEF,CAAA;AApFuH,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;AAA1GC,aAAN,GAAA;AAAA,CAgGA,CAAUA,MAAV,KAAA;AACC,EAAMA,OAAA,QAAW,GAAAF,+BAAA;AAAA,CADR,EAAAE,aAAA,KAAAA,aAAA,GAAA,EAAA,CAAA,CAAA","file":"Piece.cjs","sourcesContent":["import type { Awaitable } from '@sapphire/utilities';\nimport { container, type Container } from '../shared/Container';\nimport { PieceLocation, type PieceLocationJSON } from './PieceLocation';\nimport type { Store } from './Store';\nimport type { StoreOf, StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The context for the piece, contains extra information from the store,\n * the piece's path, and the store that loaded it.\n */\nexport interface LoaderPieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The root directory the piece was loaded from.\n\t */\n\treadonly root: string;\n\n\t/**\n\t * The path the module was loaded from, relative to {@link LoaderPieceContext.root}.\n\t */\n\treadonly path: string;\n\n\t/**\n\t * The module's name extracted from the path.\n\t */\n\treadonly name: string;\n\n\t/**\n\t * The store that loaded the piece.\n\t */\n\treadonly store: StoreOf<StoreName>;\n}\n\n/** @deprecated Use {@linkcode LoaderPieceContext} instead. */\nexport interface PieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> extends LoaderPieceContext<StoreName> {}\n\n/**\n * The options for the {@link Piece}.\n */\nexport interface PieceOptions {\n\t/**\n\t * The name for the piece.\n\t * @default ''\n\t */\n\treadonly name?: string;\n\n\t/**\n\t * Whether or not the piece should be enabled. If set to false, the piece will be unloaded.\n\t * @default true\n\t */\n\treadonly enabled?: boolean;\n}\n\n/**\n * The piece to be stored in {@link Store} instances.\n */\nexport class Piece<Options extends PieceOptions = PieceOptions, StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The store that contains the piece.\n\t */\n\tpublic readonly store: StoreOf<StoreName>;\n\n\t/**\n\t * The location metadata for the piece's file.\n\t */\n\tpublic readonly location: PieceLocation;\n\n\t/**\n\t * The name of the piece.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * Whether or not the piece is enabled.\n\t */\n\tpublic enabled: boolean;\n\n\t/**\n\t * The raw options passed to this {@link Piece}\n\t */\n\tpublic readonly options: Options;\n\n\tpublic constructor(context: Piece.LoaderContext<StoreName>, options: PieceOptions = {}) {\n\t\tthis.store = context.store;\n\t\tthis.location = new PieceLocation(context.path, context.root);\n\t\tthis.name = options.name ?? context.name;\n\t\tthis.enabled = options.enabled ?? true;\n\t\tthis.options = options as Options;\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 * Per-piece listener that is called when the piece is loaded into the store.\n\t * Useful to set-up asynchronous initialization tasks.\n\t */\n\tpublic onLoad(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Per-piece listener that is called when the piece is unloaded from the store.\n\t * Useful to set-up clean-up tasks.\n\t */\n\tpublic onUnload(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Unloads and disables the piece.\n\t */\n\tpublic async unload() {\n\t\tawait this.store.unload(this.name);\n\t\tthis.enabled = false;\n\t}\n\n\t/**\n\t * Reloads the piece by loading the same path in the store.\n\t */\n\tpublic async reload() {\n\t\tawait this.store.load(this.location.root, this.location.relative);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this piece.\n\t */\n\tpublic toJSON(): PieceJSON {\n\t\treturn {\n\t\t\tlocation: this.location.toJSON(),\n\t\t\tname: this.name,\n\t\t\tenabled: this.enabled,\n\t\t\toptions: this.options\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link Piece.toJSON}.\n */\nexport interface PieceJSON {\n\tlocation: PieceLocationJSON;\n\tname: string;\n\tenabled: boolean;\n\toptions: PieceOptions;\n}\n\nexport namespace Piece {\n\texport const Location = PieceLocation;\n\texport type Options = PieceOptions;\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type LoaderContext<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type JSON = PieceJSON;\n\texport type LocationJSON = PieceLocationJSON;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/Piece.ts"],"names":["PieceLocation","container","Piece"],"mappings":";;;;;;;;;AAuDO,IAAM,MAAA,GAAN,MAAM,MAA0G,CAAA;AAAA,EA0B/G,WAAY,CAAA,OAAA,EAAyC,OAAwB,GAAA,EAAI,EAAA;AAtBxF;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAO,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAKP;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAGf,IAAA,IAAA,CAAK,QAAQ,OAAQ,CAAA,KAAA;AACrB,IAAA,IAAA,CAAK,WAAW,IAAIA,+BAAA,CAAc,OAAQ,CAAA,IAAA,EAAM,QAAQ,IAAI,CAAA;AAC5D,IAAK,IAAA,CAAA,IAAA,GAAO,OAAQ,CAAA,IAAA,IAAQ,OAAQ,CAAA,IAAA;AACpC,IAAK,IAAA,CAAA,OAAA,GAAU,QAAQ,OAAW,IAAA,IAAA;AAClC,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AAAA;AAChB;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAuB,GAAA;AACjC,IAAO,OAAAC,uBAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,MAA6B,GAAA;AACnC,IAAO,OAAA,MAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,QAA+B,GAAA;AACrC,IAAO,OAAA,MAAA;AAAA;AACR;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAA,MAAM,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA,IAAA,CAAK,IAAI,CAAA;AACjC,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA;AAAA;AAChB;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAM,MAAA,IAAA,CAAK,MAAM,IAAK,CAAA,IAAA,CAAK,SAAS,IAAM,EAAA,IAAA,CAAK,SAAS,QAAQ,CAAA;AAAA;AACjE;AAAA;AAAA;AAAA,EAKO,MAAoB,GAAA;AAC1B,IAAO,OAAA;AAAA,MACN,QAAA,EAAU,IAAK,CAAA,QAAA,CAAS,MAAO,EAAA;AAAA,MAC/B,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,SAAS,IAAK,CAAA,OAAA;AAAA,MACd,SAAS,IAAK,CAAA;AAAA,KACf;AAAA;AAEF,CAAA;AApFuH,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;AAA1GC,aAAN,GAAA;AAAA,CAgGA,CAAUA,MAAV,KAAA;AACC,EAAMA,OAAA,QAAW,GAAAF,+BAAA;AAAA,CADR,EAAAE,aAAA,KAAAA,aAAA,GAAA,EAAA,CAAA,CAAA","file":"Piece.cjs","sourcesContent":["import type { Awaitable } from '@sapphire/utilities';\nimport { container, type Container } from '../shared/Container';\nimport { PieceLocation, type PieceLocationJSON } from './PieceLocation';\nimport type { Store } from './Store';\nimport type { StoreOf, StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The context for the piece, contains extra information from the store,\n * the piece's path, and the store that loaded it.\n */\nexport interface LoaderPieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The root directory the piece was loaded from.\n\t */\n\treadonly root: string;\n\n\t/**\n\t * The path the module was loaded from, relative to {@link LoaderPieceContext.root}.\n\t */\n\treadonly path: string;\n\n\t/**\n\t * The module's name extracted from the path.\n\t */\n\treadonly name: string;\n\n\t/**\n\t * The store that loaded the piece.\n\t */\n\treadonly store: StoreOf<StoreName>;\n}\n\n/** @deprecated Use {@linkcode LoaderPieceContext} instead. */\nexport interface PieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> extends LoaderPieceContext<StoreName> {}\n\n/**\n * The options for the {@link Piece}.\n */\nexport interface PieceOptions {\n\t/**\n\t * The name for the piece.\n\t * @default ''\n\t */\n\treadonly name?: string;\n\n\t/**\n\t * Whether or not the piece should be enabled. If set to false, the piece will be unloaded.\n\t * @default true\n\t */\n\treadonly enabled?: boolean;\n}\n\n/**\n * The piece to be stored in {@link Store} instances.\n */\nexport class Piece<Options extends PieceOptions = PieceOptions, StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The store that contains the piece.\n\t */\n\tpublic readonly store: StoreOf<StoreName>;\n\n\t/**\n\t * The location metadata for the piece's file.\n\t */\n\tpublic readonly location: PieceLocation;\n\n\t/**\n\t * The name of the piece.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * Whether or not the piece is enabled.\n\t */\n\tpublic enabled: boolean;\n\n\t/**\n\t * The raw options passed to this {@link Piece}\n\t */\n\tpublic readonly options: Options;\n\n\tpublic constructor(context: Piece.LoaderContext<StoreName>, options: PieceOptions = {}) {\n\t\tthis.store = context.store;\n\t\tthis.location = new PieceLocation(context.path, context.root);\n\t\tthis.name = options.name ?? context.name;\n\t\tthis.enabled = options.enabled ?? true;\n\t\tthis.options = options as Options;\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 * Per-piece listener that is called when the piece is loaded into the store.\n\t * Useful to set-up asynchronous initialization tasks.\n\t */\n\tpublic onLoad(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Per-piece listener that is called when the piece is unloaded from the store.\n\t * Useful to set-up clean-up tasks.\n\t */\n\tpublic onUnload(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Unloads and disables the piece.\n\t */\n\tpublic async unload() {\n\t\tawait this.store.unload(this.name);\n\t\tthis.enabled = false;\n\t}\n\n\t/**\n\t * Reloads the piece by loading the same path in the store.\n\t */\n\tpublic async reload() {\n\t\tawait this.store.load(this.location.root, this.location.relative);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this piece.\n\t */\n\tpublic toJSON(): PieceJSON {\n\t\treturn {\n\t\t\tlocation: this.location.toJSON(),\n\t\t\tname: this.name,\n\t\t\tenabled: this.enabled,\n\t\t\toptions: this.options\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link Piece.toJSON}.\n */\nexport interface PieceJSON {\n\tlocation: PieceLocationJSON;\n\tname: string;\n\tenabled: boolean;\n\toptions: PieceOptions;\n}\n\nexport namespace Piece {\n\texport const Location = PieceLocation;\n\texport type Options = PieceOptions;\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type LoaderContext<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type JSON = PieceJSON;\n\texport type LocationJSON = PieceLocationJSON;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/PieceLocation.ts"],"names":["VirtualPath","relative","sep","basename"],"mappings":";;;;;;;;;AAMO,IAAM,cAAA,GAAN,MAAM,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenB,WAAA,CAAY,MAAc,IAAc,EAAA;AAX/C;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAOf,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AACZ,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AAAA;AACb;AAAA;AAAA;AAAA,EAKA,IAAW,OAAU,GAAA;AACpB,IAAA,OAAO,KAAK,IAAS,KAAAA,yBAAA;AAAA;AACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,QAAmB,GAAA;AAC7B,IAAA,OAAO,KAAK,OAAU,GAAAA,yBAAA,GAAcC,cAAS,IAAK,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AAAA;AAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,WAAwB,GAAA;AAClC,IAAO,OAAA,IAAA,CAAK,OAAU,GAAA,EAAK,GAAA,IAAA,CAAK,QAAS,CAAA,KAAA,CAAMC,QAAG,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,CAAE,CAAA,CAAA;AAAA;AAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,IAAe,GAAA;AACzB,IAAA,OAAO,IAAK,CAAA,OAAA,GAAUF,yBAAc,GAAAG,aAAA,CAAS,KAAK,IAAI,CAAA;AAAA;AACvD;AAAA;AAAA;AAAA,EAKO,MAA4B,GAAA;AAClC,IAAO,OAAA;AAAA,MACN,aAAa,IAAK,CAAA,WAAA;AAAA,MAClB,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,UAAU,IAAK,CAAA,QAAA;AAAA,MACf,MAAM,IAAK,CAAA;AAAA,KACZ;AAAA;AAEF,CAAA;AA1F2B,MAAA,CAAA,cAAA,EAAA,eAAA,CAAA;AAApB,IAAM,aAAN,GAAA","file":"PieceLocation.cjs","sourcesContent":["import { basename, relative, sep } from 'path';\nimport { VirtualPath } from '../internal/constants';\n\n/**\n * The metadata class used for {@link Piece}s.\n */\nexport class PieceLocation {\n\t/**\n\t * The full path to the file.\n\t */\n\tpublic readonly full: string;\n\n\t/**\n\t * The root directory the file was found from.\n\t */\n\tpublic readonly root: string;\n\n\t/**\n\t * @param full The full path to the file.\n\t * @param root The root directory the file was found from.\n\t */\n\tpublic constructor(full: string, root: string) {\n\t\tthis.full = full;\n\t\tthis.root = root;\n\t}\n\n\t/**\n\t * Whether the file is virtual or not.\n\t */\n\tpublic get virtual() {\n\t\treturn this.full === VirtualPath;\n\t}\n\n\t/**\n\t * The relative path between {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/general/ping.js'\n\t * );\n\t *\n\t * console.log(location.relative);\n\t * // → 'general/ping.js'\n\t * ```\n\t */\n\tpublic get relative(): string {\n\t\treturn this.virtual ? VirtualPath : relative(this.root, this.full);\n\t}\n\n\t/**\n\t * The names of the directories that separate {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.directories);\n\t * // → ['games', 'multiplayer']\n\t * ```\n\t */\n\tpublic get directories(): string[] {\n\t\treturn this.virtual ? [] : this.relative.split(sep).slice(0, -1);\n\t}\n\n\t/**\n\t * The name and extension of the file that was loaded, extracted from {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.name);\n\t * // → 'connect-four.js'\n\t * ```\n\t */\n\tpublic get name(): string {\n\t\treturn this.virtual ? VirtualPath : basename(this.full);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this structure.\n\t */\n\tpublic toJSON(): PieceLocationJSON {\n\t\treturn {\n\t\t\tdirectories: this.directories,\n\t\t\tfull: this.full,\n\t\t\tname: this.name,\n\t\t\trelative: this.relative,\n\t\t\troot: this.root\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link PieceLocation.toJSON}.\n */\nexport interface PieceLocationJSON {\n\tdirectories: string[];\n\tfull: string;\n\tname: string;\n\trelative: string;\n\troot: string;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/PieceLocation.ts"],"names":["VirtualPath","relative","sep","basename"],"mappings":";;;;;;;;;AAMO,IAAM,cAAA,GAAN,MAAM,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenB,WAAA,CAAY,MAAc,IAAc,EAAA;AAX/C;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAOf,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AACZ,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AAAA;AACb;AAAA;AAAA;AAAA,EAKA,IAAW,OAAU,GAAA;AACpB,IAAA,OAAO,KAAK,IAAS,KAAAA,yBAAA;AAAA;AACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,QAAmB,GAAA;AAC7B,IAAA,OAAO,KAAK,OAAU,GAAAA,yBAAA,GAAcC,cAAS,IAAK,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AAAA;AAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,WAAwB,GAAA;AAClC,IAAO,OAAA,IAAA,CAAK,OAAU,GAAA,EAAK,GAAA,IAAA,CAAK,QAAS,CAAA,KAAA,CAAMC,QAAG,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,EAAE,CAAA;AAAA;AAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,IAAe,GAAA;AACzB,IAAA,OAAO,IAAK,CAAA,OAAA,GAAUF,yBAAc,GAAAG,aAAA,CAAS,KAAK,IAAI,CAAA;AAAA;AACvD;AAAA;AAAA;AAAA,EAKO,MAA4B,GAAA;AAClC,IAAO,OAAA;AAAA,MACN,aAAa,IAAK,CAAA,WAAA;AAAA,MAClB,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,UAAU,IAAK,CAAA,QAAA;AAAA,MACf,MAAM,IAAK,CAAA;AAAA,KACZ;AAAA;AAEF,CAAA;AA1F2B,MAAA,CAAA,cAAA,EAAA,eAAA,CAAA;AAApB,IAAM,aAAN,GAAA","file":"PieceLocation.cjs","sourcesContent":["import { basename, relative, sep } from 'path';\nimport { VirtualPath } from '../internal/constants';\n\n/**\n * The metadata class used for {@link Piece}s.\n */\nexport class PieceLocation {\n\t/**\n\t * The full path to the file.\n\t */\n\tpublic readonly full: string;\n\n\t/**\n\t * The root directory the file was found from.\n\t */\n\tpublic readonly root: string;\n\n\t/**\n\t * @param full The full path to the file.\n\t * @param root The root directory the file was found from.\n\t */\n\tpublic constructor(full: string, root: string) {\n\t\tthis.full = full;\n\t\tthis.root = root;\n\t}\n\n\t/**\n\t * Whether the file is virtual or not.\n\t */\n\tpublic get virtual() {\n\t\treturn this.full === VirtualPath;\n\t}\n\n\t/**\n\t * The relative path between {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/general/ping.js'\n\t * );\n\t *\n\t * console.log(location.relative);\n\t * // → 'general/ping.js'\n\t * ```\n\t */\n\tpublic get relative(): string {\n\t\treturn this.virtual ? VirtualPath : relative(this.root, this.full);\n\t}\n\n\t/**\n\t * The names of the directories that separate {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.directories);\n\t * // → ['games', 'multiplayer']\n\t * ```\n\t */\n\tpublic get directories(): string[] {\n\t\treturn this.virtual ? [] : this.relative.split(sep).slice(0, -1);\n\t}\n\n\t/**\n\t * The name and extension of the file that was loaded, extracted from {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.name);\n\t * // → 'connect-four.js'\n\t * ```\n\t */\n\tpublic get name(): string {\n\t\treturn this.virtual ? VirtualPath : basename(this.full);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this structure.\n\t */\n\tpublic toJSON(): PieceLocationJSON {\n\t\treturn {\n\t\t\tdirectories: this.directories,\n\t\t\tfull: this.full,\n\t\t\tname: this.name,\n\t\t\trelative: this.relative,\n\t\t\troot: this.root\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link PieceLocation.toJSON}.\n */\nexport interface PieceLocationJSON {\n\tdirectories: string[];\n\tfull: string;\n\tname: string;\n\trelative: string;\n\troot: string;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { Collection } from '@discordjs/collection';
2
- import { Awaitable, Constructor, Ctor, AbstractConstructor } from '@sapphire/utilities';
2
+ import { AbstractConstructor, Awaitable, Constructor, Ctor } from '@sapphire/utilities';
3
3
 
4
4
  declare enum LoaderErrorType {
5
5
  EmptyModule = "EMPTY_MODULE",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/strategies/LoaderStrategy.ts"],"names":[],"mappings":"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","file":"LoaderStrategy.mjs","sourcesContent":["import { 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';\nimport { CanLoadTypeScriptFiles } from './env';\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\tif (CanLoadTypeScriptFiles) {\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
+ {"version":3,"sources":["../../../../src/lib/strategies/LoaderStrategy.ts"],"names":[],"mappings":"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","file":"LoaderStrategy.mjs","sourcesContent":["import { 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';\nimport { CanLoadTypeScriptFiles } from './env';\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\tif (CanLoadTypeScriptFiles) {\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 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/Piece.ts"],"names":["Piece"],"mappings":";;;;AAuDO,IAAM,MAAA,GAAN,MAAM,MAA0G,CAAA;AAAA,EA0B/G,WAAY,CAAA,OAAA,EAAyC,OAAwB,GAAA,EAAI,EAAA;AAtBxF;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAO,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAKP;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAGf,IAAA,IAAA,CAAK,QAAQ,OAAQ,CAAA,KAAA;AACrB,IAAA,IAAA,CAAK,WAAW,IAAI,aAAA,CAAc,OAAQ,CAAA,IAAA,EAAM,QAAQ,IAAI,CAAA;AAC5D,IAAK,IAAA,CAAA,IAAA,GAAO,OAAQ,CAAA,IAAA,IAAQ,OAAQ,CAAA,IAAA;AACpC,IAAK,IAAA,CAAA,OAAA,GAAU,QAAQ,OAAW,IAAA,IAAA;AAClC,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AAAA;AAChB;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAuB,GAAA;AACjC,IAAO,OAAA,SAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,MAA6B,GAAA;AACnC,IAAO,OAAA,KAAA,CAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,QAA+B,GAAA;AACrC,IAAO,OAAA,KAAA,CAAA;AAAA;AACR;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAA,MAAM,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA,IAAA,CAAK,IAAI,CAAA;AACjC,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA;AAAA;AAChB;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAM,MAAA,IAAA,CAAK,MAAM,IAAK,CAAA,IAAA,CAAK,SAAS,IAAM,EAAA,IAAA,CAAK,SAAS,QAAQ,CAAA;AAAA;AACjE;AAAA;AAAA;AAAA,EAKO,MAAoB,GAAA;AAC1B,IAAO,OAAA;AAAA,MACN,QAAA,EAAU,IAAK,CAAA,QAAA,CAAS,MAAO,EAAA;AAAA,MAC/B,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,SAAS,IAAK,CAAA,OAAA;AAAA,MACd,SAAS,IAAK,CAAA;AAAA,KACf;AAAA;AAEF,CAAA;AApFuH,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;AAAhH,IAAM,KAAN,GAAA;AAAA,CAgGA,CAAUA,MAAV,KAAA;AACC,EAAMA,OAAA,QAAW,GAAA,aAAA;AAAA,CADR,EAAA,KAAA,KAAA,KAAA,GAAA,EAAA,CAAA,CAAA","file":"Piece.mjs","sourcesContent":["import type { Awaitable } from '@sapphire/utilities';\nimport { container, type Container } from '../shared/Container';\nimport { PieceLocation, type PieceLocationJSON } from './PieceLocation';\nimport type { Store } from './Store';\nimport type { StoreOf, StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The context for the piece, contains extra information from the store,\n * the piece's path, and the store that loaded it.\n */\nexport interface LoaderPieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The root directory the piece was loaded from.\n\t */\n\treadonly root: string;\n\n\t/**\n\t * The path the module was loaded from, relative to {@link LoaderPieceContext.root}.\n\t */\n\treadonly path: string;\n\n\t/**\n\t * The module's name extracted from the path.\n\t */\n\treadonly name: string;\n\n\t/**\n\t * The store that loaded the piece.\n\t */\n\treadonly store: StoreOf<StoreName>;\n}\n\n/** @deprecated Use {@linkcode LoaderPieceContext} instead. */\nexport interface PieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> extends LoaderPieceContext<StoreName> {}\n\n/**\n * The options for the {@link Piece}.\n */\nexport interface PieceOptions {\n\t/**\n\t * The name for the piece.\n\t * @default ''\n\t */\n\treadonly name?: string;\n\n\t/**\n\t * Whether or not the piece should be enabled. If set to false, the piece will be unloaded.\n\t * @default true\n\t */\n\treadonly enabled?: boolean;\n}\n\n/**\n * The piece to be stored in {@link Store} instances.\n */\nexport class Piece<Options extends PieceOptions = PieceOptions, StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The store that contains the piece.\n\t */\n\tpublic readonly store: StoreOf<StoreName>;\n\n\t/**\n\t * The location metadata for the piece's file.\n\t */\n\tpublic readonly location: PieceLocation;\n\n\t/**\n\t * The name of the piece.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * Whether or not the piece is enabled.\n\t */\n\tpublic enabled: boolean;\n\n\t/**\n\t * The raw options passed to this {@link Piece}\n\t */\n\tpublic readonly options: Options;\n\n\tpublic constructor(context: Piece.LoaderContext<StoreName>, options: PieceOptions = {}) {\n\t\tthis.store = context.store;\n\t\tthis.location = new PieceLocation(context.path, context.root);\n\t\tthis.name = options.name ?? context.name;\n\t\tthis.enabled = options.enabled ?? true;\n\t\tthis.options = options as Options;\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 * Per-piece listener that is called when the piece is loaded into the store.\n\t * Useful to set-up asynchronous initialization tasks.\n\t */\n\tpublic onLoad(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Per-piece listener that is called when the piece is unloaded from the store.\n\t * Useful to set-up clean-up tasks.\n\t */\n\tpublic onUnload(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Unloads and disables the piece.\n\t */\n\tpublic async unload() {\n\t\tawait this.store.unload(this.name);\n\t\tthis.enabled = false;\n\t}\n\n\t/**\n\t * Reloads the piece by loading the same path in the store.\n\t */\n\tpublic async reload() {\n\t\tawait this.store.load(this.location.root, this.location.relative);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this piece.\n\t */\n\tpublic toJSON(): PieceJSON {\n\t\treturn {\n\t\t\tlocation: this.location.toJSON(),\n\t\t\tname: this.name,\n\t\t\tenabled: this.enabled,\n\t\t\toptions: this.options\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link Piece.toJSON}.\n */\nexport interface PieceJSON {\n\tlocation: PieceLocationJSON;\n\tname: string;\n\tenabled: boolean;\n\toptions: PieceOptions;\n}\n\nexport namespace Piece {\n\texport const Location = PieceLocation;\n\texport type Options = PieceOptions;\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type LoaderContext<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type JSON = PieceJSON;\n\texport type LocationJSON = PieceLocationJSON;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/Piece.ts"],"names":["Piece"],"mappings":";;;;AAuDO,IAAM,MAAA,GAAN,MAAM,MAA0G,CAAA;AAAA,EA0B/G,WAAY,CAAA,OAAA,EAAyC,OAAwB,GAAA,EAAI,EAAA;AAtBxF;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAO,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAKP;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAGf,IAAA,IAAA,CAAK,QAAQ,OAAQ,CAAA,KAAA;AACrB,IAAA,IAAA,CAAK,WAAW,IAAI,aAAA,CAAc,OAAQ,CAAA,IAAA,EAAM,QAAQ,IAAI,CAAA;AAC5D,IAAK,IAAA,CAAA,IAAA,GAAO,OAAQ,CAAA,IAAA,IAAQ,OAAQ,CAAA,IAAA;AACpC,IAAK,IAAA,CAAA,OAAA,GAAU,QAAQ,OAAW,IAAA,IAAA;AAClC,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AAAA;AAChB;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAuB,GAAA;AACjC,IAAO,OAAA,SAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,MAA6B,GAAA;AACnC,IAAO,OAAA,MAAA;AAAA;AACR;AAAA;AAAA;AAAA;AAAA,EAMO,QAA+B,GAAA;AACrC,IAAO,OAAA,MAAA;AAAA;AACR;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAA,MAAM,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA,IAAA,CAAK,IAAI,CAAA;AACjC,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA;AAAA;AAChB;AAAA;AAAA;AAAA,EAKA,MAAa,MAAS,GAAA;AACrB,IAAM,MAAA,IAAA,CAAK,MAAM,IAAK,CAAA,IAAA,CAAK,SAAS,IAAM,EAAA,IAAA,CAAK,SAAS,QAAQ,CAAA;AAAA;AACjE;AAAA;AAAA;AAAA,EAKO,MAAoB,GAAA;AAC1B,IAAO,OAAA;AAAA,MACN,QAAA,EAAU,IAAK,CAAA,QAAA,CAAS,MAAO,EAAA;AAAA,MAC/B,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,SAAS,IAAK,CAAA,OAAA;AAAA,MACd,SAAS,IAAK,CAAA;AAAA,KACf;AAAA;AAEF,CAAA;AApFuH,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;AAAhH,IAAM,KAAN,GAAA;AAAA,CAgGA,CAAUA,MAAV,KAAA;AACC,EAAMA,OAAA,QAAW,GAAA,aAAA;AAAA,CADR,EAAA,KAAA,KAAA,KAAA,GAAA,EAAA,CAAA,CAAA","file":"Piece.mjs","sourcesContent":["import type { Awaitable } from '@sapphire/utilities';\nimport { container, type Container } from '../shared/Container';\nimport { PieceLocation, type PieceLocationJSON } from './PieceLocation';\nimport type { Store } from './Store';\nimport type { StoreOf, StoreRegistryKey } from './StoreRegistry';\n\n/**\n * The context for the piece, contains extra information from the store,\n * the piece's path, and the store that loaded it.\n */\nexport interface LoaderPieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The root directory the piece was loaded from.\n\t */\n\treadonly root: string;\n\n\t/**\n\t * The path the module was loaded from, relative to {@link LoaderPieceContext.root}.\n\t */\n\treadonly path: string;\n\n\t/**\n\t * The module's name extracted from the path.\n\t */\n\treadonly name: string;\n\n\t/**\n\t * The store that loaded the piece.\n\t */\n\treadonly store: StoreOf<StoreName>;\n}\n\n/** @deprecated Use {@linkcode LoaderPieceContext} instead. */\nexport interface PieceContext<StoreName extends StoreRegistryKey = StoreRegistryKey> extends LoaderPieceContext<StoreName> {}\n\n/**\n * The options for the {@link Piece}.\n */\nexport interface PieceOptions {\n\t/**\n\t * The name for the piece.\n\t * @default ''\n\t */\n\treadonly name?: string;\n\n\t/**\n\t * Whether or not the piece should be enabled. If set to false, the piece will be unloaded.\n\t * @default true\n\t */\n\treadonly enabled?: boolean;\n}\n\n/**\n * The piece to be stored in {@link Store} instances.\n */\nexport class Piece<Options extends PieceOptions = PieceOptions, StoreName extends StoreRegistryKey = StoreRegistryKey> {\n\t/**\n\t * The store that contains the piece.\n\t */\n\tpublic readonly store: StoreOf<StoreName>;\n\n\t/**\n\t * The location metadata for the piece's file.\n\t */\n\tpublic readonly location: PieceLocation;\n\n\t/**\n\t * The name of the piece.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * Whether or not the piece is enabled.\n\t */\n\tpublic enabled: boolean;\n\n\t/**\n\t * The raw options passed to this {@link Piece}\n\t */\n\tpublic readonly options: Options;\n\n\tpublic constructor(context: Piece.LoaderContext<StoreName>, options: PieceOptions = {}) {\n\t\tthis.store = context.store;\n\t\tthis.location = new PieceLocation(context.path, context.root);\n\t\tthis.name = options.name ?? context.name;\n\t\tthis.enabled = options.enabled ?? true;\n\t\tthis.options = options as Options;\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 * Per-piece listener that is called when the piece is loaded into the store.\n\t * Useful to set-up asynchronous initialization tasks.\n\t */\n\tpublic onLoad(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Per-piece listener that is called when the piece is unloaded from the store.\n\t * Useful to set-up clean-up tasks.\n\t */\n\tpublic onUnload(): Awaitable<unknown> {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Unloads and disables the piece.\n\t */\n\tpublic async unload() {\n\t\tawait this.store.unload(this.name);\n\t\tthis.enabled = false;\n\t}\n\n\t/**\n\t * Reloads the piece by loading the same path in the store.\n\t */\n\tpublic async reload() {\n\t\tawait this.store.load(this.location.root, this.location.relative);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this piece.\n\t */\n\tpublic toJSON(): PieceJSON {\n\t\treturn {\n\t\t\tlocation: this.location.toJSON(),\n\t\t\tname: this.name,\n\t\t\tenabled: this.enabled,\n\t\t\toptions: this.options\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link Piece.toJSON}.\n */\nexport interface PieceJSON {\n\tlocation: PieceLocationJSON;\n\tname: string;\n\tenabled: boolean;\n\toptions: PieceOptions;\n}\n\nexport namespace Piece {\n\texport const Location = PieceLocation;\n\texport type Options = PieceOptions;\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type LoaderContext<StoreName extends StoreRegistryKey = StoreRegistryKey> = LoaderPieceContext<StoreName>;\n\texport type JSON = PieceJSON;\n\texport type LocationJSON = PieceLocationJSON;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/PieceLocation.ts"],"names":[],"mappings":";;;;AAMO,IAAM,cAAA,GAAN,MAAM,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenB,WAAA,CAAY,MAAc,IAAc,EAAA;AAX/C;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAOf,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AACZ,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AAAA;AACb;AAAA;AAAA;AAAA,EAKA,IAAW,OAAU,GAAA;AACpB,IAAA,OAAO,KAAK,IAAS,KAAA,WAAA;AAAA;AACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,QAAmB,GAAA;AAC7B,IAAA,OAAO,KAAK,OAAU,GAAA,WAAA,GAAc,SAAS,IAAK,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AAAA;AAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,WAAwB,GAAA;AAClC,IAAO,OAAA,IAAA,CAAK,OAAU,GAAA,EAAK,GAAA,IAAA,CAAK,QAAS,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,CAAE,CAAA,CAAA;AAAA;AAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,IAAe,GAAA;AACzB,IAAA,OAAO,IAAK,CAAA,OAAA,GAAU,WAAc,GAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA;AACvD;AAAA;AAAA;AAAA,EAKO,MAA4B,GAAA;AAClC,IAAO,OAAA;AAAA,MACN,aAAa,IAAK,CAAA,WAAA;AAAA,MAClB,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,UAAU,IAAK,CAAA,QAAA;AAAA,MACf,MAAM,IAAK,CAAA;AAAA,KACZ;AAAA;AAEF,CAAA;AA1F2B,MAAA,CAAA,cAAA,EAAA,eAAA,CAAA;AAApB,IAAM,aAAN,GAAA","file":"PieceLocation.mjs","sourcesContent":["import { basename, relative, sep } from 'path';\nimport { VirtualPath } from '../internal/constants';\n\n/**\n * The metadata class used for {@link Piece}s.\n */\nexport class PieceLocation {\n\t/**\n\t * The full path to the file.\n\t */\n\tpublic readonly full: string;\n\n\t/**\n\t * The root directory the file was found from.\n\t */\n\tpublic readonly root: string;\n\n\t/**\n\t * @param full The full path to the file.\n\t * @param root The root directory the file was found from.\n\t */\n\tpublic constructor(full: string, root: string) {\n\t\tthis.full = full;\n\t\tthis.root = root;\n\t}\n\n\t/**\n\t * Whether the file is virtual or not.\n\t */\n\tpublic get virtual() {\n\t\treturn this.full === VirtualPath;\n\t}\n\n\t/**\n\t * The relative path between {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/general/ping.js'\n\t * );\n\t *\n\t * console.log(location.relative);\n\t * // → 'general/ping.js'\n\t * ```\n\t */\n\tpublic get relative(): string {\n\t\treturn this.virtual ? VirtualPath : relative(this.root, this.full);\n\t}\n\n\t/**\n\t * The names of the directories that separate {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.directories);\n\t * // → ['games', 'multiplayer']\n\t * ```\n\t */\n\tpublic get directories(): string[] {\n\t\treturn this.virtual ? [] : this.relative.split(sep).slice(0, -1);\n\t}\n\n\t/**\n\t * The name and extension of the file that was loaded, extracted from {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.name);\n\t * // → 'connect-four.js'\n\t * ```\n\t */\n\tpublic get name(): string {\n\t\treturn this.virtual ? VirtualPath : basename(this.full);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this structure.\n\t */\n\tpublic toJSON(): PieceLocationJSON {\n\t\treturn {\n\t\t\tdirectories: this.directories,\n\t\t\tfull: this.full,\n\t\t\tname: this.name,\n\t\t\trelative: this.relative,\n\t\t\troot: this.root\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link PieceLocation.toJSON}.\n */\nexport interface PieceLocationJSON {\n\tdirectories: string[];\n\tfull: string;\n\tname: string;\n\trelative: string;\n\troot: string;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/PieceLocation.ts"],"names":[],"mappings":";;;;AAMO,IAAM,cAAA,GAAN,MAAM,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenB,WAAA,CAAY,MAAc,IAAc,EAAA;AAX/C;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAKhB;AAAA;AAAA;AAAA,IAAgB,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAOf,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AACZ,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AAAA;AACb;AAAA;AAAA;AAAA,EAKA,IAAW,OAAU,GAAA;AACpB,IAAA,OAAO,KAAK,IAAS,KAAA,WAAA;AAAA;AACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,QAAmB,GAAA;AAC7B,IAAA,OAAO,KAAK,OAAU,GAAA,WAAA,GAAc,SAAS,IAAK,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AAAA;AAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,WAAwB,GAAA;AAClC,IAAO,OAAA,IAAA,CAAK,OAAU,GAAA,EAAK,GAAA,IAAA,CAAK,QAAS,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,EAAE,CAAA;AAAA;AAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAW,IAAe,GAAA;AACzB,IAAA,OAAO,IAAK,CAAA,OAAA,GAAU,WAAc,GAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA;AACvD;AAAA;AAAA;AAAA,EAKO,MAA4B,GAAA;AAClC,IAAO,OAAA;AAAA,MACN,aAAa,IAAK,CAAA,WAAA;AAAA,MAClB,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,UAAU,IAAK,CAAA,QAAA;AAAA,MACf,MAAM,IAAK,CAAA;AAAA,KACZ;AAAA;AAEF,CAAA;AA1F2B,MAAA,CAAA,cAAA,EAAA,eAAA,CAAA;AAApB,IAAM,aAAN,GAAA","file":"PieceLocation.mjs","sourcesContent":["import { basename, relative, sep } from 'path';\nimport { VirtualPath } from '../internal/constants';\n\n/**\n * The metadata class used for {@link Piece}s.\n */\nexport class PieceLocation {\n\t/**\n\t * The full path to the file.\n\t */\n\tpublic readonly full: string;\n\n\t/**\n\t * The root directory the file was found from.\n\t */\n\tpublic readonly root: string;\n\n\t/**\n\t * @param full The full path to the file.\n\t * @param root The root directory the file was found from.\n\t */\n\tpublic constructor(full: string, root: string) {\n\t\tthis.full = full;\n\t\tthis.root = root;\n\t}\n\n\t/**\n\t * Whether the file is virtual or not.\n\t */\n\tpublic get virtual() {\n\t\treturn this.full === VirtualPath;\n\t}\n\n\t/**\n\t * The relative path between {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/general/ping.js'\n\t * );\n\t *\n\t * console.log(location.relative);\n\t * // → 'general/ping.js'\n\t * ```\n\t */\n\tpublic get relative(): string {\n\t\treturn this.virtual ? VirtualPath : relative(this.root, this.full);\n\t}\n\n\t/**\n\t * The names of the directories that separate {@link PieceLocation.root} and {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.directories);\n\t * // → ['games', 'multiplayer']\n\t * ```\n\t */\n\tpublic get directories(): string[] {\n\t\treturn this.virtual ? [] : this.relative.split(sep).slice(0, -1);\n\t}\n\n\t/**\n\t * The name and extension of the file that was loaded, extracted from {@link PieceLocation.full}.\n\t * @example\n\t * ```typescript\n\t * const location = new PieceLocation(\n\t * \t'/usr/src/app/commands',\n\t * \t'/usr/src/app/commands/games/multiplayer/connect-four.js'\n\t * );\n\t *\n\t * console.log(location.name);\n\t * // → 'connect-four.js'\n\t * ```\n\t */\n\tpublic get name(): string {\n\t\treturn this.virtual ? VirtualPath : basename(this.full);\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` behavior of this structure.\n\t */\n\tpublic toJSON(): PieceLocationJSON {\n\t\treturn {\n\t\t\tdirectories: this.directories,\n\t\t\tfull: this.full,\n\t\t\tname: this.name,\n\t\t\trelative: this.relative,\n\t\t\troot: this.root\n\t\t};\n\t}\n}\n\n/**\n * The return type of {@link PieceLocation.toJSON}.\n */\nexport interface PieceLocationJSON {\n\tdirectories: string[];\n\tfull: string;\n\tname: string;\n\trelative: string;\n\troot: string;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapphire/pieces",
3
- "version": "4.3.2-next.7ea1702",
3
+ "version": "4.3.2-next.901b3bd",
4
4
  "description": "Sapphire's piece loader.",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/esm/index.mjs",
@@ -26,7 +26,7 @@
26
26
  "test": "vitest run",
27
27
  "build": "tsup && concurrently \"yarn:postbuild:*\"",
28
28
  "postbuild:internal": "node scripts/make-import.mjs",
29
- "postbuild:types:cjs": "rollup-type-bundler -d dist/cjs -ot .cts",
29
+ "postbuild:types:cjs": "rollup-type-bundler -d dist/cjs --output-typings-file-extension .cts",
30
30
  "postbuild:types:esm": "rollup-type-bundler -d dist/esm -t .mts",
31
31
  "typecheck": "tsc -b src",
32
32
  "bump": "cliff-jumper",
@@ -35,36 +35,36 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@discordjs/collection": "^1.5.3",
38
- "@sapphire/utilities": "^3.18.1",
38
+ "@sapphire/utilities": "^3.18.2",
39
39
  "tslib": "^2.8.1"
40
40
  },
41
41
  "devDependencies": {
42
- "@commitlint/cli": "^19.6.0",
43
- "@commitlint/config-conventional": "^19.6.0",
44
- "@favware/cliff-jumper": "^5.0.0",
42
+ "@commitlint/cli": "^19.8.0",
43
+ "@commitlint/config-conventional": "^19.8.0",
44
+ "@favware/cliff-jumper": "^6.0.0",
45
45
  "@favware/npm-deprecate": "^2.0.0",
46
- "@favware/rollup-type-bundler": "^3.3.0",
46
+ "@favware/rollup-type-bundler": "^4.0.0",
47
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": "^22.10.1",
50
+ "@types/node": "^22.13.10",
51
51
  "@typescript-eslint/eslint-plugin": "^7.13.1",
52
52
  "@typescript-eslint/parser": "^7.13.1",
53
- "@vitest/coverage-v8": "^2.1.8",
54
- "concurrently": "^9.1.0",
53
+ "@vitest/coverage-v8": "^3.0.8",
54
+ "concurrently": "^9.1.2",
55
55
  "cz-conventional-changelog": "^3.3.0",
56
56
  "esbuild-plugin-file-path-extensions": "^2.1.4",
57
57
  "eslint": "^8.57.1",
58
- "eslint-config-prettier": "^9.1.0",
59
- "eslint-plugin-prettier": "^5.2.1",
60
- "lint-staged": "^15.2.10",
61
- "prettier": "^3.4.2",
58
+ "eslint-config-prettier": "^10.1.1",
59
+ "eslint-plugin-prettier": "^5.2.3",
60
+ "lint-staged": "^15.5.0",
61
+ "prettier": "^3.5.3",
62
62
  "rimraf": "^6.0.1",
63
- "tsup": "^8.3.5",
63
+ "tsup": "^8.4.0",
64
64
  "typedoc": "^0.26.11",
65
65
  "typedoc-json-parser": "^10.2.0",
66
66
  "typescript": "^5.5.2",
67
- "vitest": "^2.1.8"
67
+ "vitest": "^3.0.8"
68
68
  },
69
69
  "repository": {
70
70
  "type": "git",
@@ -108,10 +108,10 @@
108
108
  "access": "public"
109
109
  },
110
110
  "resolutions": {
111
- "acorn": "^8.14.0",
111
+ "acorn": "^8.14.1",
112
112
  "ansi-regex": "^5.0.1",
113
113
  "minimist": "^1.2.8"
114
114
  },
115
115
  "prettier": "@sapphire/prettier-config",
116
- "packageManager": "yarn@4.5.3"
116
+ "packageManager": "yarn@4.7.0"
117
117
  }