commandkit 1.0.0-dev.20250704125205 → 1.0.0-dev.20250705124848

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.
Files changed (79) hide show
  1. package/dist/{CommandKit-DkPVD3wV.js → CommandKit-DuH9iT2t.js} +4 -4
  2. package/dist/{CommandKit-DkPVD3wV.js.map → CommandKit-DuH9iT2t.js.map} +1 -1
  3. package/dist/CommandKit.js +4 -4
  4. package/dist/CommandKitEventsChannel-BSdcgY3Q.js.map +1 -1
  5. package/dist/CommandsRouter-Bs9UuowL.js.map +1 -1
  6. package/dist/{MessageCommandParser-CUZrGknY.js → MessageCommandParser-CGhN3xNN.js} +2 -2
  7. package/dist/{MessageCommandParser-CUZrGknY.js.map → MessageCommandParser-CGhN3xNN.js.map} +1 -1
  8. package/dist/analytics/analytics-engine.js +4 -4
  9. package/dist/analytics/utils.js +4 -4
  10. package/dist/app/commands/AppCommandRunner.js +4 -4
  11. package/dist/app/commands/Context.js +4 -4
  12. package/dist/app/commands/MessageCommandParser.js +2 -2
  13. package/dist/app/handlers/AppCommandHandler.js +4 -4
  14. package/dist/app/handlers/AppEventsHandler.js +4 -4
  15. package/dist/app/index.js +4 -4
  16. package/dist/app/interrupt/signals.js +2 -2
  17. package/dist/app/register/CommandRegistrar.js +4 -4
  18. package/dist/app-process-CMtPJoA5.js.map +1 -1
  19. package/dist/{build--FBgqYjI.js → build-CICWK6YT.js} +2 -2
  20. package/dist/{build--FBgqYjI.js.map → build-CICWK6YT.js.map} +1 -1
  21. package/dist/cli/build.js +5 -5
  22. package/dist/cli/development.js +5 -5
  23. package/dist/cli/development.js.map +1 -1
  24. package/dist/cli/generators.js.map +1 -1
  25. package/dist/cli/information.js +1 -1
  26. package/dist/cli/information.js.map +1 -1
  27. package/dist/cli/init.js +5 -5
  28. package/dist/cli/production.js +5 -5
  29. package/dist/common-Cx8Kw8DO.js.map +1 -1
  30. package/dist/components/index.js +4 -4
  31. package/dist/components/v1/button/Button.js +4 -4
  32. package/dist/components/v1/button/ButtonKit.js +4 -4
  33. package/dist/components/v1/modal/Modal.js +4 -4
  34. package/dist/components/v1/modal/ModalKit.js +4 -4
  35. package/dist/components/v1/select-menu/ChannelSelectMenuKit.js +4 -4
  36. package/dist/components/v1/select-menu/MentionableSelectMenuKit.js +4 -4
  37. package/dist/components/v1/select-menu/RoleSelectMenuKit.js +4 -4
  38. package/dist/components/v1/select-menu/SelectMenu.js +4 -4
  39. package/dist/components/v1/select-menu/StringSelectMenuKit.js +4 -4
  40. package/dist/components/v1/select-menu/UserSelectMenuKit.js +4 -4
  41. package/dist/config/config.js +4 -4
  42. package/dist/config/default.js +4 -4
  43. package/dist/config/loader.js +4 -4
  44. package/dist/constants-R96vEAFD.js.map +1 -1
  45. package/dist/context/async-context.js +4 -4
  46. package/dist/context/environment.js +4 -4
  47. package/dist/{error-codes-DXOuid4c.js → error-codes-C-ViHyu-.js} +2 -2
  48. package/dist/{error-codes-DXOuid4c.js.map → error-codes-C-ViHyu-.js.map} +1 -1
  49. package/dist/{feature-flags-DJcINI5E.js → feature-flags-D-KWdT5L.js} +2 -2
  50. package/dist/{feature-flags-DJcINI5E.js.map → feature-flags-D-KWdT5L.js.map} +1 -1
  51. package/dist/flags/feature-flags.js +5 -5
  52. package/dist/index.js +7 -7
  53. package/dist/{init-DeoDd5cK.js → init-Ccmk0dsY.js} +2 -2
  54. package/dist/{init-DeoDd5cK.js.map → init-Ccmk0dsY.js.map} +1 -1
  55. package/dist/kv/kv.js.map +1 -1
  56. package/dist/logger/DefaultLogger.js +4 -4
  57. package/dist/logger/Logger.js +4 -4
  58. package/dist/plugins/index.js +4 -4
  59. package/dist/plugins/plugin-runtime/CommandKitPluginRuntime.js +4 -4
  60. package/dist/plugins/plugin-runtime/CompilerPluginRuntime.js +4 -4
  61. package/dist/plugins/plugin-runtime/builtin/CommonDirectiveTransformer.js +4 -4
  62. package/dist/plugins/plugin-runtime/builtin/MacroPlugin.js +4 -4
  63. package/dist/resolve-file-url-9aPt6A_n.js.map +1 -1
  64. package/dist/{signals-lSAO5hOr.js → signals-Bu7gndaS.js} +2 -2
  65. package/dist/{signals-lSAO5hOr.js.map → signals-Bu7gndaS.js.map} +1 -1
  66. package/dist/type-checker-BATr8TiL.js.map +1 -1
  67. package/dist/utils/colors.d.ts +2 -2
  68. package/dist/utils/dev-hooks.js +4 -4
  69. package/dist/utils/error-codes.js +1 -1
  70. package/dist/utils/useful-stuff/async-queue.js +3 -3
  71. package/dist/utils/useful-stuff/async-queue.js.map +1 -1
  72. package/dist/utils/useful-stuff/mutex.js.map +1 -1
  73. package/dist/utils/useful-stuff/semaphore.js.map +1 -1
  74. package/dist/utils/utilities.js +4 -4
  75. package/dist/utils/warn-unstable.js.map +1 -1
  76. package/dist/{version-D4sNeC-Z.js → version-CJ67UJGw.js} +2 -2
  77. package/dist/{version-D4sNeC-Z.js.map → version-CJ67UJGw.js.map} +1 -1
  78. package/dist/version.js +1 -1
  79. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flags-DJcINI5E.js","names":[],"sources":["../src/flags/feature-flags.ts"],"sourcesContent":["import { getCommandKit, getContext } from '../context/async-context';\nimport { eventWorkerContext } from '../app/events/EventWorkerContext';\nimport { ParsedEvent } from '../app/router';\nimport { CommandKit } from '../CommandKit';\nimport {\n AutocompleteInteraction,\n ChatInputCommandInteraction,\n Client,\n ClientEvents,\n ContextMenuCommandInteraction,\n Guild,\n Message,\n TextBasedChannel,\n} from 'discord.js';\nimport { LoadedCommand } from '../app';\nimport { defer, JsonSerialize } from '../utils/utilities';\nimport { AnalyticsEvents } from '../analytics/constants';\nimport { FlagProvider, FlagConfiguration } from './FlagProvider';\nimport { Logger } from '../logger/Logger';\n\n// Global flag provider\nlet flagProvider: FlagProvider | null = null;\n\n/**\n * Set the global flag provider for all feature flags\n */\nexport function setFlagProvider(provider: FlagProvider): void {\n flagProvider = provider;\n}\n\n/**\n * @private\n */\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Function type for identifying entities in the context of feature flags.\n * This function should return an object representing the entity that will be used\n * to evaluate the feature flag.\n * It can be synchronous or asynchronous.\n */\nexport type IdentifyFunction<R> = (\n context: EvaluationContext,\n) => MaybePromise<R>;\n\n/**\n * Function type for deciding the outcome of a feature flag based on the provided entities.\n * This function receives an object containing the entities and optionally the provider configuration,\n * and should return the result of the decision.\n * It can be synchronous or asynchronous.\n */\nexport type DecideFunction<E, R> = (data: {\n entities: E;\n provider?: FlagConfiguration | null;\n}) => MaybePromise<R>;\n\n/**\n * Definition for a feature flag, including its key, description, identify function,\n * and decide function.\n * The identify function is used to determine the entities that will be evaluated\n * against the feature flag, while the decide function contains the logic for\n * determining the outcome of the flag based on those entities.\n */\nexport interface FeatureFlagDefinition<R, Entity> {\n /**\n * Unique key for the feature flag.\n * Should be a string that identifies the flag.\n */\n key: string;\n /**\n * Optional description of the feature flag.\n * This can be used for documentation or debugging purposes.\n */\n description?: string;\n /**\n * Optional flag to enable integration with an external flag provider.\n * If true, the flag will use the global flag provider to determine its state.\n * Default: false\n */\n identify?: IdentifyFunction<Entity>;\n /**\n * Function to decide the outcome of the feature flag.\n * This function receives the identified entities and should return the result of the decision.\n */\n decide: DecideFunction<Entity, R>;\n /**\n * Whether to disable analytics tracking for this flag.\n * Default: false\n */\n disableAnalytics?: boolean;\n}\n\n/**\n * Context for evaluating command flags in CommandKit.\n */\nexport interface CommandFlagContext {\n /**\n * The Discord client instance.\n * This is the main entry point for interacting with the Discord API.\n */\n client: Client<true>;\n /**\n * The CommandKit instance, which provides access to the command framework.\n * This includes commands, events, and other features of CommandKit.\n */\n commandkit: CommandKit;\n /**\n * The command context, which includes information about the command being executed.\n * This can include the interaction, message, guild, channel, and the loaded command.\n */\n command: {\n /**\n * The interaction object if the command was invoked via an interaction.\n * This can be a ChatInputCommandInteraction, AutocompleteInteraction, or ContextMenuCommandInteraction.\n */\n interaction?:\n | ChatInputCommandInteraction\n | AutocompleteInteraction\n | ContextMenuCommandInteraction;\n /**\n * The message object if the command was invoked via a message.\n */\n message?: Message;\n /**\n * The guild where the command was invoked, if applicable.\n * This will be null for commands invoked in DMs.\n */\n guild: Guild | null;\n /**\n * The channel where the command was invoked.\n * This can be a text channel, DM channel, or any other type of text-based channel.\n */\n channel: TextBasedChannel | null;\n /**\n * The loaded command instance that is being executed.\n * This contains the command's metadata and logic.\n */\n command: LoadedCommand;\n };\n /**\n * The event context is null for command flags, as they are not tied to a specific event.\n * This is used to differentiate between command and event flags.\n */\n event: null;\n}\n\n/**\n * Context for evaluating event flags in CommandKit.\n */\nexport interface EventFlagContext {\n /**\n * The Discord client instance.\n * This is the main entry point for interacting with the Discord API.\n */\n client: Client<true>;\n /**\n * The CommandKit instance, which provides access to the command framework.\n * This includes commands, events, and other features of CommandKit.\n */\n commandkit: CommandKit;\n /**\n * The event context, which includes information about the event being processed.\n * This can include the parsed event data, the event name, and the namespace if applicable.\n */\n event: {\n /**\n * The parsed event data, which contains the raw data from the event.\n * This can include information like user IDs, channel IDs, and other relevant data.\n */\n data: ParsedEvent;\n /**\n * The name of the event being processed.\n * This is the string identifier for the event, such as 'messageCreate' or 'guildMemberAdd'.\n */\n event: string;\n /**\n * The namespace of the event, if applicable.\n * This can be used to group related events or commands together.\n * It is null if the event does not belong to a specific namespace.\n */\n namespace: string | null;\n /**\n * The arguments passed to the event handler.\n * This is an array of arguments that were passed when the event was triggered.\n * It can be used to access specific data related to the event.\n */\n arguments: any[];\n /**\n * A function to retrieve the arguments for a specific event type.\n * This allows for type-safe access to the arguments based on the event name.\n * @param event - The name of the event to retrieve arguments for.\n */\n argumentsAs<E extends keyof ClientEvents>(event: E): ClientEvents[E];\n };\n /**\n * The command context is null for event flags, as they are not tied to a specific command.\n * This is used to differentiate between command and event flags.\n */\n command: null;\n}\n\n/**\n * Combined context type for feature flag evaluation.\n */\nexport type EvaluationContext = CommandFlagContext | EventFlagContext;\n\n/**\n * Function type for custom evaluation of feature flags.\n * This function can be used to provide a custom evaluation context for the flag.\n * It should return an object representing the entities to be evaluated.\n */\nexport type CustomEvaluationFunction<E> = () => MaybePromise<E>;\n\n/**\n * Context for custom evaluation of feature flags.\n * This allows for more flexible evaluation based on custom logic or external data.\n * The identify function can be a direct object or a function that returns the entities.\n */\nexport type CustomEvaluationContext<E> = {\n /**\n * Optional function to identify the entities for evaluation.\n * This can be a function that returns the entities based on the current context.\n */\n identify: E | CustomEvaluationFunction<E>;\n};\n\nexport interface FlagRunner<E, R> {\n /**\n * Execute the feature flag evaluation with the provided entities.\n * This method will run the identify and decide functions to determine the flag's outcome.\n * @param res - Optional entities to use for evaluation. If not provided, it will call the identify function.\n * @returns A promise that resolves to the result of the feature flag evaluation.\n */\n (): Promise<R>;\n /**\n * Run the feature flag evaluation with a custom context.\n * This allows for more flexible evaluation based on custom logic or external data.\n * @param context - The custom evaluation context containing the identify function or object.\n * @returns A promise that resolves to the result of the feature flag evaluation.\n */\n run(context: CustomEvaluationContext<E>): Promise<R>;\n}\n\n/**\n * Class representing a feature flag in CommandKit.\n */\nexport class FeatureFlag<R, T> {\n private commandkit: CommandKit;\n\n /**\n * Create a new feature flag.\n * @param options - The options for the feature flag.\n */\n public constructor(public readonly options: FeatureFlagDefinition<R, T>) {\n this.commandkit = getCommandKit(true);\n const FlagStore = this.commandkit.flags;\n\n if (FlagStore.has(options.key)) {\n throw new Error(`Feature flag with key \"${options.key}\" already exists.`);\n }\n\n FlagStore.set(options.key, this);\n }\n\n private getContext(): EvaluationContext {\n const env = getContext();\n\n if (env?.context) {\n const {\n client,\n commandkit,\n interaction,\n message,\n guild,\n channel,\n command,\n } = env.context;\n\n return {\n client: client as Client<true>,\n commandkit,\n command: {\n interaction,\n message,\n guild,\n channel,\n command,\n },\n event: null,\n };\n }\n\n const eventCtx = eventWorkerContext.getStore();\n\n if (eventCtx) {\n const { commandkit, data, event, namespace } = eventCtx;\n\n return {\n client: commandkit.client as Client<true>,\n commandkit,\n event: {\n data,\n event,\n namespace,\n arguments: eventCtx.arguments,\n argumentsAs: (eventName) => {\n const args = eventCtx.arguments as ClientEvents[typeof eventName];\n return args;\n },\n },\n command: null,\n };\n }\n\n throw new Error(\n 'Could not determine the execution context. Feature flags may only be used inside a command or event.',\n );\n }\n\n /**\n * Execute the feature flag evaluation.\n * @param res - Optional entities to use for evaluation. If not provided, it will call the identify function.\n * @returns A promise that resolves to the result of the feature flag evaluation.\n */\n public async execute(res?: T): Promise<R> {\n const { decide, identify, disableAnalytics } = this.options;\n\n const identificationStart = performance.now();\n const entities =\n res ??\n (await (async () => {\n const ctx = this.getContext();\n return (await identify?.(ctx)) ?? ({} as T);\n })());\n const identificationTime = performance.now() - identificationStart;\n\n // Get provider configuration if global provider is available\n let providerConfig: FlagConfiguration | null = null;\n if (flagProvider) {\n try {\n providerConfig = await flagProvider.getFlag(this.options.key, entities);\n\n // If provider says flag is disabled, return early with default behavior\n if (providerConfig && !providerConfig.enabled) {\n // For boolean flags, return false; for others, let decide function handle it\n if (typeof decide === 'function') {\n const decisionResult = await decide({\n entities,\n provider: providerConfig,\n });\n return decisionResult as R;\n }\n }\n } catch (error) {\n Logger.error(\n `Error fetching flag provider configuration for \"${this.options.key}\": ${error}`,\n );\n // continue with local decision if provider fails\n }\n }\n\n const decisionStart = performance.now();\n const decisionResult = await decide({\n entities,\n provider: providerConfig,\n });\n const decisionTime = performance.now() - decisionStart;\n\n // Skip analytics if disabled\n if (!disableAnalytics) {\n defer(async () => {\n await this.commandkit.analytics.track({\n name: AnalyticsEvents.FEATURE_FLAG_METRICS,\n data: {\n flag: this.options.key,\n identificationTime: identificationTime.toFixed(2),\n decisionTime: decisionTime.toFixed(2),\n usedProvider: flagProvider !== null,\n providerEnabled: providerConfig?.enabled ?? null,\n },\n });\n });\n\n defer(async () => {\n await this.commandkit.analytics.track({\n name: AnalyticsEvents.FEATURE_FLAG_DECISION,\n id:\n entities &&\n typeof entities === 'object' &&\n 'id' in entities &&\n typeof entities.id === 'string'\n ? entities.id\n : undefined,\n data: {\n flag: this.options.key,\n decision: JsonSerialize(decisionResult, 'unknown'),\n providerUsed: flagProvider !== null,\n },\n });\n });\n }\n\n return decisionResult as R;\n }\n}\n\n/**\n * Create a new feature flag.\n * @param options - The options for the feature flag.\n * @returns A new instance of the FeatureFlag class.\n */\nexport function flag<Returns = boolean, Entity = Record<any, any>>(\n options: FeatureFlagDefinition<Returns, Entity>,\n): FlagRunner<Entity, Returns> {\n const flag = new FeatureFlag<Returns, Entity>(options);\n const runner = flag.execute.bind(flag, undefined) as FlagRunner<\n Entity,\n Returns\n >;\n\n runner.run = async function (ctx) {\n if (!ctx?.identify) {\n throw new Error(\n 'Custom evaluation context must have an identify function or object.',\n );\n }\n\n const context = (\n typeof ctx === 'function'\n ? await (ctx as CustomEvaluationFunction<Entity>)()\n : ctx\n ) as Entity;\n\n const decisionResult = await flag.execute(context);\n\n return decisionResult;\n };\n\n return runner;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"feature-flags-D-KWdT5L.js","names":[],"sources":["../src/flags/feature-flags.ts"],"sourcesContent":["import { getCommandKit, getContext } from '../context/async-context';\nimport { eventWorkerContext } from '../app/events/EventWorkerContext';\nimport { ParsedEvent } from '../app/router';\nimport { CommandKit } from '../CommandKit';\nimport {\n AutocompleteInteraction,\n ChatInputCommandInteraction,\n Client,\n ClientEvents,\n ContextMenuCommandInteraction,\n Guild,\n Message,\n TextBasedChannel,\n} from 'discord.js';\nimport { LoadedCommand } from '../app';\nimport { defer, JsonSerialize } from '../utils/utilities';\nimport { AnalyticsEvents } from '../analytics/constants';\nimport { FlagProvider, FlagConfiguration } from './FlagProvider';\nimport { Logger } from '../logger/Logger';\n\n// Global flag provider\nlet flagProvider: FlagProvider | null = null;\n\n/**\n * Set the global flag provider for all feature flags\n */\nexport function setFlagProvider(provider: FlagProvider): void {\n flagProvider = provider;\n}\n\n/**\n * @private\n */\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Function type for identifying entities in the context of feature flags.\n * This function should return an object representing the entity that will be used\n * to evaluate the feature flag.\n * It can be synchronous or asynchronous.\n */\nexport type IdentifyFunction<R> = (\n context: EvaluationContext,\n) => MaybePromise<R>;\n\n/**\n * Function type for deciding the outcome of a feature flag based on the provided entities.\n * This function receives an object containing the entities and optionally the provider configuration,\n * and should return the result of the decision.\n * It can be synchronous or asynchronous.\n */\nexport type DecideFunction<E, R> = (data: {\n entities: E;\n provider?: FlagConfiguration | null;\n}) => MaybePromise<R>;\n\n/**\n * Definition for a feature flag, including its key, description, identify function,\n * and decide function.\n * The identify function is used to determine the entities that will be evaluated\n * against the feature flag, while the decide function contains the logic for\n * determining the outcome of the flag based on those entities.\n */\nexport interface FeatureFlagDefinition<R, Entity> {\n /**\n * Unique key for the feature flag.\n * Should be a string that identifies the flag.\n */\n key: string;\n /**\n * Optional description of the feature flag.\n * This can be used for documentation or debugging purposes.\n */\n description?: string;\n /**\n * Optional flag to enable integration with an external flag provider.\n * If true, the flag will use the global flag provider to determine its state.\n * Default: false\n */\n identify?: IdentifyFunction<Entity>;\n /**\n * Function to decide the outcome of the feature flag.\n * This function receives the identified entities and should return the result of the decision.\n */\n decide: DecideFunction<Entity, R>;\n /**\n * Whether to disable analytics tracking for this flag.\n * Default: false\n */\n disableAnalytics?: boolean;\n}\n\n/**\n * Context for evaluating command flags in CommandKit.\n */\nexport interface CommandFlagContext {\n /**\n * The Discord client instance.\n * This is the main entry point for interacting with the Discord API.\n */\n client: Client<true>;\n /**\n * The CommandKit instance, which provides access to the command framework.\n * This includes commands, events, and other features of CommandKit.\n */\n commandkit: CommandKit;\n /**\n * The command context, which includes information about the command being executed.\n * This can include the interaction, message, guild, channel, and the loaded command.\n */\n command: {\n /**\n * The interaction object if the command was invoked via an interaction.\n * This can be a ChatInputCommandInteraction, AutocompleteInteraction, or ContextMenuCommandInteraction.\n */\n interaction?:\n | ChatInputCommandInteraction\n | AutocompleteInteraction\n | ContextMenuCommandInteraction;\n /**\n * The message object if the command was invoked via a message.\n */\n message?: Message;\n /**\n * The guild where the command was invoked, if applicable.\n * This will be null for commands invoked in DMs.\n */\n guild: Guild | null;\n /**\n * The channel where the command was invoked.\n * This can be a text channel, DM channel, or any other type of text-based channel.\n */\n channel: TextBasedChannel | null;\n /**\n * The loaded command instance that is being executed.\n * This contains the command's metadata and logic.\n */\n command: LoadedCommand;\n };\n /**\n * The event context is null for command flags, as they are not tied to a specific event.\n * This is used to differentiate between command and event flags.\n */\n event: null;\n}\n\n/**\n * Context for evaluating event flags in CommandKit.\n */\nexport interface EventFlagContext {\n /**\n * The Discord client instance.\n * This is the main entry point for interacting with the Discord API.\n */\n client: Client<true>;\n /**\n * The CommandKit instance, which provides access to the command framework.\n * This includes commands, events, and other features of CommandKit.\n */\n commandkit: CommandKit;\n /**\n * The event context, which includes information about the event being processed.\n * This can include the parsed event data, the event name, and the namespace if applicable.\n */\n event: {\n /**\n * The parsed event data, which contains the raw data from the event.\n * This can include information like user IDs, channel IDs, and other relevant data.\n */\n data: ParsedEvent;\n /**\n * The name of the event being processed.\n * This is the string identifier for the event, such as 'messageCreate' or 'guildMemberAdd'.\n */\n event: string;\n /**\n * The namespace of the event, if applicable.\n * This can be used to group related events or commands together.\n * It is null if the event does not belong to a specific namespace.\n */\n namespace: string | null;\n /**\n * The arguments passed to the event handler.\n * This is an array of arguments that were passed when the event was triggered.\n * It can be used to access specific data related to the event.\n */\n arguments: any[];\n /**\n * A function to retrieve the arguments for a specific event type.\n * This allows for type-safe access to the arguments based on the event name.\n * @param event - The name of the event to retrieve arguments for.\n */\n argumentsAs<E extends keyof ClientEvents>(event: E): ClientEvents[E];\n };\n /**\n * The command context is null for event flags, as they are not tied to a specific command.\n * This is used to differentiate between command and event flags.\n */\n command: null;\n}\n\n/**\n * Combined context type for feature flag evaluation.\n */\nexport type EvaluationContext = CommandFlagContext | EventFlagContext;\n\n/**\n * Function type for custom evaluation of feature flags.\n * This function can be used to provide a custom evaluation context for the flag.\n * It should return an object representing the entities to be evaluated.\n */\nexport type CustomEvaluationFunction<E> = () => MaybePromise<E>;\n\n/**\n * Context for custom evaluation of feature flags.\n * This allows for more flexible evaluation based on custom logic or external data.\n * The identify function can be a direct object or a function that returns the entities.\n */\nexport type CustomEvaluationContext<E> = {\n /**\n * Optional function to identify the entities for evaluation.\n * This can be a function that returns the entities based on the current context.\n */\n identify: E | CustomEvaluationFunction<E>;\n};\n\nexport interface FlagRunner<E, R> {\n /**\n * Execute the feature flag evaluation with the provided entities.\n * This method will run the identify and decide functions to determine the flag's outcome.\n * @param res - Optional entities to use for evaluation. If not provided, it will call the identify function.\n * @returns A promise that resolves to the result of the feature flag evaluation.\n */\n (): Promise<R>;\n /**\n * Run the feature flag evaluation with a custom context.\n * This allows for more flexible evaluation based on custom logic or external data.\n * @param context - The custom evaluation context containing the identify function or object.\n * @returns A promise that resolves to the result of the feature flag evaluation.\n */\n run(context: CustomEvaluationContext<E>): Promise<R>;\n}\n\n/**\n * Class representing a feature flag in CommandKit.\n */\nexport class FeatureFlag<R, T> {\n private commandkit: CommandKit;\n\n /**\n * Create a new feature flag.\n * @param options - The options for the feature flag.\n */\n public constructor(public readonly options: FeatureFlagDefinition<R, T>) {\n this.commandkit = getCommandKit(true);\n const FlagStore = this.commandkit.flags;\n\n if (FlagStore.has(options.key)) {\n throw new Error(`Feature flag with key \"${options.key}\" already exists.`);\n }\n\n FlagStore.set(options.key, this);\n }\n\n private getContext(): EvaluationContext {\n const env = getContext();\n\n if (env?.context) {\n const {\n client,\n commandkit,\n interaction,\n message,\n guild,\n channel,\n command,\n } = env.context;\n\n return {\n client: client as Client<true>,\n commandkit,\n command: {\n interaction,\n message,\n guild,\n channel,\n command,\n },\n event: null,\n };\n }\n\n const eventCtx = eventWorkerContext.getStore();\n\n if (eventCtx) {\n const { commandkit, data, event, namespace } = eventCtx;\n\n return {\n client: commandkit.client as Client<true>,\n commandkit,\n event: {\n data,\n event,\n namespace,\n arguments: eventCtx.arguments,\n argumentsAs: (eventName) => {\n const args = eventCtx.arguments as ClientEvents[typeof eventName];\n return args;\n },\n },\n command: null,\n };\n }\n\n throw new Error(\n 'Could not determine the execution context. Feature flags may only be used inside a command or event.',\n );\n }\n\n /**\n * Execute the feature flag evaluation.\n * @param res - Optional entities to use for evaluation. If not provided, it will call the identify function.\n * @returns A promise that resolves to the result of the feature flag evaluation.\n */\n public async execute(res?: T): Promise<R> {\n const { decide, identify, disableAnalytics } = this.options;\n\n const identificationStart = performance.now();\n const entities =\n res ??\n (await (async () => {\n const ctx = this.getContext();\n return (await identify?.(ctx)) ?? ({} as T);\n })());\n const identificationTime = performance.now() - identificationStart;\n\n // Get provider configuration if global provider is available\n let providerConfig: FlagConfiguration | null = null;\n if (flagProvider) {\n try {\n providerConfig = await flagProvider.getFlag(this.options.key, entities);\n\n // If provider says flag is disabled, return early with default behavior\n if (providerConfig && !providerConfig.enabled) {\n // For boolean flags, return false; for others, let decide function handle it\n if (typeof decide === 'function') {\n const decisionResult = await decide({\n entities,\n provider: providerConfig,\n });\n return decisionResult as R;\n }\n }\n } catch (error) {\n Logger.error(\n `Error fetching flag provider configuration for \"${this.options.key}\": ${error}`,\n );\n // continue with local decision if provider fails\n }\n }\n\n const decisionStart = performance.now();\n const decisionResult = await decide({\n entities,\n provider: providerConfig,\n });\n const decisionTime = performance.now() - decisionStart;\n\n // Skip analytics if disabled\n if (!disableAnalytics) {\n defer(async () => {\n await this.commandkit.analytics.track({\n name: AnalyticsEvents.FEATURE_FLAG_METRICS,\n data: {\n flag: this.options.key,\n identificationTime: identificationTime.toFixed(2),\n decisionTime: decisionTime.toFixed(2),\n usedProvider: flagProvider !== null,\n providerEnabled: providerConfig?.enabled ?? null,\n },\n });\n });\n\n defer(async () => {\n await this.commandkit.analytics.track({\n name: AnalyticsEvents.FEATURE_FLAG_DECISION,\n id:\n entities &&\n typeof entities === 'object' &&\n 'id' in entities &&\n typeof entities.id === 'string'\n ? entities.id\n : undefined,\n data: {\n flag: this.options.key,\n decision: JsonSerialize(decisionResult, 'unknown'),\n providerUsed: flagProvider !== null,\n },\n });\n });\n }\n\n return decisionResult as R;\n }\n}\n\n/**\n * Create a new feature flag.\n * @param options - The options for the feature flag.\n * @returns A new instance of the FeatureFlag class.\n */\nexport function flag<Returns = boolean, Entity = Record<any, any>>(\n options: FeatureFlagDefinition<Returns, Entity>,\n): FlagRunner<Entity, Returns> {\n const flag = new FeatureFlag<Returns, Entity>(options);\n const runner = flag.execute.bind(flag, undefined) as FlagRunner<\n Entity,\n Returns\n >;\n\n runner.run = async function (ctx) {\n if (!ctx?.identify) {\n throw new Error(\n 'Custom evaluation context must have an identify function or object.',\n );\n }\n\n const context = (\n typeof ctx === 'function'\n ? await (ctx as CustomEvaluationFunction<Entity>)()\n : ctx\n ) as Entity;\n\n const decisionResult = await flag.execute(context);\n\n return decisionResult;\n };\n\n return runner;\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  require('../colors-Cd4Oz-r-.js');
2
2
  require('../ActionRow-CmTHbo2t.js');
3
- require('../error-codes-DXOuid4c.js');
4
- require('../CommandKit-DkPVD3wV.js');
3
+ require('../error-codes-C-ViHyu-.js');
4
+ require('../CommandKit-DuH9iT2t.js');
5
5
  require('../common-CcfjYnPG.js');
6
6
  require('../common-vnMIelAE.js');
7
7
  require('../container-DCjIgp-B.js');
@@ -23,16 +23,16 @@ require('../runtime-5fxB4uhe.js');
23
23
  require('../resolve-file-url-9aPt6A_n.js');
24
24
  require('../types-package-MDczrp9f.js');
25
25
  require('../EventWorkerContext-DxfS_0fJ.js');
26
- require('../signals-lSAO5hOr.js');
26
+ require('../signals-Bu7gndaS.js');
27
27
  require('../constants-R96vEAFD.js');
28
- require('../MessageCommandParser-CUZrGknY.js');
28
+ require('../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../CommandsRouter-Bs9UuowL.js');
30
30
  require('../EventsRouter-B7oifgM6.js');
31
31
  require('../router-wA3kFzES.js');
32
32
  require('../common-Cx8Kw8DO.js');
33
33
  require('../CommandKitEventsChannel-BSdcgY3Q.js');
34
34
  require('../store-CyzliDXj.js');
35
- const require_feature_flags = require('../feature-flags-DJcINI5E.js');
35
+ const require_feature_flags = require('../feature-flags-D-KWdT5L.js');
36
36
 
37
37
  exports.FeatureFlag = require_feature_flags.FeatureFlag;
38
38
  exports.flag = require_feature_flags.flag;
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
  require('./colors-Cd4Oz-r-.js');
3
3
  const require_ActionRow = require('./ActionRow-CmTHbo2t.js');
4
- require('./error-codes-DXOuid4c.js');
5
- const require_CommandKit = require('./CommandKit-DkPVD3wV.js');
4
+ require('./error-codes-C-ViHyu-.js');
5
+ const require_CommandKit = require('./CommandKit-DuH9iT2t.js');
6
6
  require('./common-CcfjYnPG.js');
7
7
  require('./common-vnMIelAE.js');
8
8
  const require_container = require('./container-DCjIgp-B.js');
@@ -24,9 +24,9 @@ require('./runtime-5fxB4uhe.js');
24
24
  require('./resolve-file-url-9aPt6A_n.js');
25
25
  require('./types-package-MDczrp9f.js');
26
26
  const require_EventWorkerContext = require('./EventWorkerContext-DxfS_0fJ.js');
27
- const require_signals = require('./signals-lSAO5hOr.js');
27
+ const require_signals = require('./signals-Bu7gndaS.js');
28
28
  require('./constants-R96vEAFD.js');
29
- const require_MessageCommandParser = require('./MessageCommandParser-CUZrGknY.js');
29
+ const require_MessageCommandParser = require('./MessageCommandParser-CGhN3xNN.js');
30
30
  const require_CommandsRouter = require('./CommandsRouter-Bs9UuowL.js');
31
31
  const require_EventsRouter = require('./EventsRouter-B7oifgM6.js');
32
32
  require('./router-wA3kFzES.js');
@@ -36,9 +36,9 @@ require('./store-CyzliDXj.js');
36
36
  const require_helpers = require('./helpers-DfV6HlgI.js');
37
37
  require('./app-gCenKq8k.js');
38
38
  require('./ILogger-BMIMljYD.js');
39
- const require_version = require('./version-D4sNeC-Z.js');
40
- const require_feature_flags = require('./feature-flags-DJcINI5E.js');
41
- const require_init = require('./init-DeoDd5cK.js');
39
+ const require_version = require('./version-CJ67UJGw.js');
40
+ const require_feature_flags = require('./feature-flags-D-KWdT5L.js');
41
+ const require_init = require('./init-Ccmk0dsY.js');
42
42
 
43
43
  //#region src/index.ts
44
44
  var src_default = require_CommandKit.CommandKit;
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require('./chunk-nOFOJqeH.js');
2
- const require_CommandKit = require('./CommandKit-DkPVD3wV.js');
2
+ const require_CommandKit = require('./CommandKit-DuH9iT2t.js');
3
3
  const require_CompilerPlugin = require('./CompilerPlugin-CjoZAAR8.js');
4
4
  const require_types_package = require('./types-package-MDczrp9f.js');
5
5
  const require_common = require('./common-Cx8Kw8DO.js');
@@ -88,4 +88,4 @@ Object.defineProperty(exports, 'bootstrapCommandkitCLI', {
88
88
  return bootstrapCommandkitCLI;
89
89
  }
90
90
  });
91
- //# sourceMappingURL=init-DeoDd5cK.js.map
91
+ //# sourceMappingURL=init-Ccmk0dsY.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init-DeoDd5cK.js","names":[],"sources":["../src/cli/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { generateTypesPackage } from '../utils/types-package';\nimport { loadConfigFile } from '../config/loader';\nimport {\n CompilerPlugin,\n CompilerPluginRuntime,\n isCompilerPlugin,\n} from '../plugins';\nimport { panic } from './common';\n\n/**\n * Creates a command line interface for CommandKit.\n * @param argv The arguments passed to the CLI.\n * @param options The options passed to the CLI.\n */\nexport async function bootstrapCommandkitCLI(\n argv: string[],\n options?: import('commander').ParseOptions | undefined,\n) {\n process.title = 'CommandKit CLI';\n\n // imports are lazily loaded when the cli is used, instead of loading it with the lib itself\n const { Command } = await import('commander');\n const { bootstrapDevelopmentServer } = await import('./development');\n const { bootstrapProductionServer, createProductionBuild } = await import(\n './production'\n );\n const { generateCommand, generateEvent } = await import('./generators');\n const { version } = await import('../version');\n const { showInformation } = await import('./information');\n const { setCLIEnv } = await import('./env');\n\n const program = new Command('commandkit');\n\n program\n .command('dev')\n .version(version)\n .description('Start your bot in development mode.')\n .option(\n '-c, --config [path]',\n 'Path to your commandkit config file.',\n './commandkit.js',\n )\n .action(() => {\n const options = program.opts();\n bootstrapDevelopmentServer(options.config);\n });\n\n program\n .command('info')\n .description(\n 'Show information about the system which can be used to report bugs.',\n )\n .action(async () => {\n await showInformation();\n });\n\n program\n .command('start')\n .description(\n 'Start your bot in production mode after running the build command.',\n )\n .option('-c, --config [path]', 'Path to your commandkit config file.')\n .action(() => {\n const options = program.opts();\n bootstrapProductionServer(options.config);\n });\n\n program\n .command('build')\n .description('Build your project for production usage.')\n .option('-c, --config [path]', 'Path to your commandkit config file.')\n .action(() => {\n setCLIEnv();\n const options = program.opts();\n return createProductionBuild(options.config);\n });\n\n program\n .command('create')\n .description(\n 'Create new files using built-in templates or custom plugin templates',\n )\n .argument(\n '<template>',\n 'The template to use (e.g. command, event, or custom plugin template)',\n )\n .argument('[args...]', 'Additional arguments for the template')\n .action(async (template, args) => {\n setCLIEnv();\n\n // Handle custom plugin templates\n const { plugins } = await loadConfigFile();\n const runtime = new CompilerPluginRuntime(\n plugins.filter((p) => isCompilerPlugin(p)) as CompilerPlugin[],\n );\n\n try {\n await runtime.init();\n const templateHandler = runtime.getTemplate(template);\n\n if (!templateHandler) {\n // Handle built-in templates\n if (template === 'command') {\n const [name] = args;\n if (!name) {\n panic('Command name is required');\n }\n await generateCommand(name);\n return;\n }\n\n if (template === 'event') {\n const [name] = args;\n if (!name) {\n panic('Event name is required');\n }\n await generateEvent(name);\n return;\n }\n\n const valid = Array.from(\n new Set([\n 'command',\n 'event',\n ...Array.from(runtime.getTemplates().keys()),\n ]),\n ).map((t) => `\"${t}\"`);\n\n panic(\n `Template \"${template}\" not found. Available templates: ${valid.join(', ')}`,\n );\n }\n\n await templateHandler(args);\n } catch (e: any) {\n panic(`Failed to execute template \"${template}\": ${e?.message || e}`);\n } finally {\n await runtime.destroy();\n }\n });\n\n const types = join(process.cwd(), 'node_modules', 'commandkit-types');\n\n if (!existsSync(types)) {\n await mkdir(types, { recursive: true }).catch(() => {});\n await generateTypesPackage(true).catch(() => {});\n }\n\n await program.parseAsync(argv, options);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,eAAsB,uBACtB,MACA,SACA;AACE,SAAQ,QAAQ;CAGhB,MAAM,EAAE,SAAS,GAAG,MAAM,OAAO;CACjC,MAAM,EAAE,4BAA4B,GAAG,2CAAM;CAC7C,MAAM,EAAE,2BAA2B,uBAAuB,GAAG,2CAAM;CAGnE,MAAM,EAAE,iBAAiB,eAAe,GAAG,2CAAM;CACjD,MAAM,EAAE,SAAS,GAAG,2CAAM;CAC1B,MAAM,EAAE,iBAAiB,GAAG,2CAAM;CAClC,MAAM,EAAE,WAAW,GAAG,2CAAM;CAE5B,MAAM,UAAU,IAAI,QAAQ;AAE5B,SACA,QAAQ,MAAM,CACd,QAAQ,QAAQ,CAChB,YAAY,sCAAsC,CAClD,OACE,uBACA,wCACA,kBACD,CACD,OAAO,MAAM;EACX,MAAM,YAAU,QAAQ,MAAM;AAC9B,6BAA2B,UAAQ,OAAO;CAC3C,EAAC;AAEF,SACA,QAAQ,OAAO,CACf,YACE,sEACD,CACD,OAAO,YAAY;AACjB,QAAM,iBAAiB;CACxB,EAAC;AAEF,SACA,QAAQ,QAAQ,CAChB,YACE,qEACD,CACD,OAAO,uBAAuB,uCAAuC,CACrE,OAAO,MAAM;EACX,MAAM,YAAU,QAAQ,MAAM;AAC9B,4BAA0B,UAAQ,OAAO;CAC1C,EAAC;AAEF,SACA,QAAQ,QAAQ,CAChB,YAAY,2CAA2C,CACvD,OAAO,uBAAuB,uCAAuC,CACrE,OAAO,MAAM;AACX,aAAW;EACX,MAAM,YAAU,QAAQ,MAAM;AAC9B,SAAO,sBAAsB,UAAQ,OAAO;CAC7C,EAAC;AAEF,SACA,QAAQ,SAAS,CACjB,YACE,uEACD,CACD,SACE,cACA,uEACD,CACD,SAAS,aAAa,wCAAwC,CAC9D,OAAO,OAAO,UAAU,SAAS;AAC/B,aAAW;EAGX,MAAM,EAAE,SAAS,GAAG,MAAM,mCAAgB;EAC1C,MAAM,UAAU,IAAI,yCAClB,QAAQ,OAAO,CAAC,MAAM,wCAAiB,EAAE,CAAC;AAG5C,MAAI;AACF,SAAM,QAAQ,MAAM;GACpB,MAAM,kBAAkB,QAAQ,YAAY,SAAS;AAErD,QAAK,iBAAiB;AAEpB,QAAI,aAAa,WAAW;KAC1B,MAAM,CAAC,KAAK,GAAG;AACf,UAAK,KACH,sBAAM,2BAA2B;AAEnC,WAAM,gBAAgB,KAAK;AAC3B;IACD;AAED,QAAI,aAAa,SAAS;KACxB,MAAM,CAAC,KAAK,GAAG;AACf,UAAK,KACH,sBAAM,yBAAyB;AAEjC,WAAM,cAAc,KAAK;AACzB;IACD;IAED,MAAM,QAAQ,MAAM,KAClB,IAAI,IAAI;KACR;KACA;KACA,GAAG,MAAM,KAAK,QAAQ,cAAc,CAAC,MAAM,CAAC;IAAC,GAE9C,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG;AAEtB,0BACG,YAAY,SAAS,oCAAoC,MAAM,KAAK,KAAK,CAAC,EAC5E;GACF;AAED,SAAM,gBAAgB,KAAK;EAC5B,SAAQ,GAAQ;AACf,yBAAO,8BAA8B,SAAS,4CAAK,EAAG,YAAW,EAAE,EAAE;EACtE,UAAS;AACR,SAAM,QAAQ,SAAS;EACxB;CACF,EAAC;CAEF,MAAM,QAAQ,oBAAK,QAAQ,KAAK,EAAE,gBAAgB,mBAAmB;AAErE,MAAK,wBAAW,MAAM,EAAE;AACtB,QAAM,4BAAM,OAAO,EAAE,WAAW,KAAM,EAAC,CAAC,MAAM,MAAM,CAAE,EAAC;AACvD,QAAM,2CAAqB,KAAK,CAAC,MAAM,MAAM,CAAE,EAAC;CAClD;AAEA,OAAM,QAAQ,WAAW,MAAM,QAAQ;AACzC"}
1
+ {"version":3,"file":"init-Ccmk0dsY.js","names":[],"sources":["../src/cli/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { generateTypesPackage } from '../utils/types-package';\nimport { loadConfigFile } from '../config/loader';\nimport {\n CompilerPlugin,\n CompilerPluginRuntime,\n isCompilerPlugin,\n} from '../plugins';\nimport { panic } from './common';\n\n/**\n * Creates a command line interface for CommandKit.\n * @param argv The arguments passed to the CLI.\n * @param options The options passed to the CLI.\n */\nexport async function bootstrapCommandkitCLI(\n argv: string[],\n options?: import('commander').ParseOptions | undefined,\n) {\n process.title = 'CommandKit CLI';\n\n // imports are lazily loaded when the cli is used, instead of loading it with the lib itself\n const { Command } = await import('commander');\n const { bootstrapDevelopmentServer } = await import('./development');\n const { bootstrapProductionServer, createProductionBuild } = await import(\n './production'\n );\n const { generateCommand, generateEvent } = await import('./generators');\n const { version } = await import('../version');\n const { showInformation } = await import('./information');\n const { setCLIEnv } = await import('./env');\n\n const program = new Command('commandkit');\n\n program\n .command('dev')\n .version(version)\n .description('Start your bot in development mode.')\n .option(\n '-c, --config [path]',\n 'Path to your commandkit config file.',\n './commandkit.js',\n )\n .action(() => {\n const options = program.opts();\n bootstrapDevelopmentServer(options.config);\n });\n\n program\n .command('info')\n .description(\n 'Show information about the system which can be used to report bugs.',\n )\n .action(async () => {\n await showInformation();\n });\n\n program\n .command('start')\n .description(\n 'Start your bot in production mode after running the build command.',\n )\n .option('-c, --config [path]', 'Path to your commandkit config file.')\n .action(() => {\n const options = program.opts();\n bootstrapProductionServer(options.config);\n });\n\n program\n .command('build')\n .description('Build your project for production usage.')\n .option('-c, --config [path]', 'Path to your commandkit config file.')\n .action(() => {\n setCLIEnv();\n const options = program.opts();\n return createProductionBuild(options.config);\n });\n\n program\n .command('create')\n .description(\n 'Create new files using built-in templates or custom plugin templates',\n )\n .argument(\n '<template>',\n 'The template to use (e.g. command, event, or custom plugin template)',\n )\n .argument('[args...]', 'Additional arguments for the template')\n .action(async (template, args) => {\n setCLIEnv();\n\n // Handle custom plugin templates\n const { plugins } = await loadConfigFile();\n const runtime = new CompilerPluginRuntime(\n plugins.filter((p) => isCompilerPlugin(p)) as CompilerPlugin[],\n );\n\n try {\n await runtime.init();\n const templateHandler = runtime.getTemplate(template);\n\n if (!templateHandler) {\n // Handle built-in templates\n if (template === 'command') {\n const [name] = args;\n if (!name) {\n panic('Command name is required');\n }\n await generateCommand(name);\n return;\n }\n\n if (template === 'event') {\n const [name] = args;\n if (!name) {\n panic('Event name is required');\n }\n await generateEvent(name);\n return;\n }\n\n const valid = Array.from(\n new Set([\n 'command',\n 'event',\n ...Array.from(runtime.getTemplates().keys()),\n ]),\n ).map((t) => `\"${t}\"`);\n\n panic(\n `Template \"${template}\" not found. Available templates: ${valid.join(', ')}`,\n );\n }\n\n await templateHandler(args);\n } catch (e: any) {\n panic(`Failed to execute template \"${template}\": ${e?.message || e}`);\n } finally {\n await runtime.destroy();\n }\n });\n\n const types = join(process.cwd(), 'node_modules', 'commandkit-types');\n\n if (!existsSync(types)) {\n await mkdir(types, { recursive: true }).catch(() => {});\n await generateTypesPackage(true).catch(() => {});\n }\n\n await program.parseAsync(argv, options);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,eAAsB,uBACtB,MACA,SACA;AACE,SAAQ,QAAQ;CAGhB,MAAM,EAAE,SAAS,GAAG,MAAM,OAAO;CACjC,MAAM,EAAE,4BAA4B,GAAG,2CAAM;CAC7C,MAAM,EAAE,2BAA2B,uBAAuB,GAAG,2CAAM;CAGnE,MAAM,EAAE,iBAAiB,eAAe,GAAG,2CAAM;CACjD,MAAM,EAAE,SAAS,GAAG,2CAAM;CAC1B,MAAM,EAAE,iBAAiB,GAAG,2CAAM;CAClC,MAAM,EAAE,WAAW,GAAG,2CAAM;CAE5B,MAAM,UAAU,IAAI,QAAQ;AAE5B,SACA,QAAQ,MAAM,CACd,QAAQ,QAAQ,CAChB,YAAY,sCAAsC,CAClD,OACE,uBACA,wCACA,kBACD,CACD,OAAO,MAAM;EACX,MAAM,YAAU,QAAQ,MAAM;AAC9B,6BAA2B,UAAQ,OAAO;CAC3C,EAAC;AAEF,SACA,QAAQ,OAAO,CACf,YACE,sEACD,CACD,OAAO,YAAY;AACjB,QAAM,iBAAiB;CACxB,EAAC;AAEF,SACA,QAAQ,QAAQ,CAChB,YACE,qEACD,CACD,OAAO,uBAAuB,uCAAuC,CACrE,OAAO,MAAM;EACX,MAAM,YAAU,QAAQ,MAAM;AAC9B,4BAA0B,UAAQ,OAAO;CAC1C,EAAC;AAEF,SACA,QAAQ,QAAQ,CAChB,YAAY,2CAA2C,CACvD,OAAO,uBAAuB,uCAAuC,CACrE,OAAO,MAAM;AACX,aAAW;EACX,MAAM,YAAU,QAAQ,MAAM;AAC9B,SAAO,sBAAsB,UAAQ,OAAO;CAC7C,EAAC;AAEF,SACA,QAAQ,SAAS,CACjB,YACE,uEACD,CACD,SACE,cACA,uEACD,CACD,SAAS,aAAa,wCAAwC,CAC9D,OAAO,OAAO,UAAU,SAAS;AAC/B,aAAW;EAGX,MAAM,EAAE,SAAS,GAAG,MAAM,mCAAgB;EAC1C,MAAM,UAAU,IAAI,yCAClB,QAAQ,OAAO,CAAC,MAAM,wCAAiB,EAAE,CAAC;AAG5C,MAAI;AACF,SAAM,QAAQ,MAAM;GACpB,MAAM,kBAAkB,QAAQ,YAAY,SAAS;AAErD,QAAK,iBAAiB;AAEpB,QAAI,aAAa,WAAW;KAC1B,MAAM,CAAC,KAAK,GAAG;AACf,UAAK,KACH,sBAAM,2BAA2B;AAEnC,WAAM,gBAAgB,KAAK;AAC3B;IACD;AAED,QAAI,aAAa,SAAS;KACxB,MAAM,CAAC,KAAK,GAAG;AACf,UAAK,KACH,sBAAM,yBAAyB;AAEjC,WAAM,cAAc,KAAK;AACzB;IACD;IAED,MAAM,QAAQ,MAAM,KAClB,IAAI,IAAI;KACR;KACA;KACA,GAAG,MAAM,KAAK,QAAQ,cAAc,CAAC,MAAM,CAAC;IAAC,GAE9C,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG;AAEtB,0BACG,YAAY,SAAS,oCAAoC,MAAM,KAAK,KAAK,GAC3E;GACF;AAED,SAAM,gBAAgB,KAAK;EAC5B,SAAQ,GAAQ;AACf,yBAAO,8BAA8B,SAAS,4CAAK,EAAG,YAAW,IAAI;EACtE,UAAS;AACR,SAAM,QAAQ,SAAS;EACxB;CACF,EAAC;CAEF,MAAM,QAAQ,oBAAK,QAAQ,KAAK,EAAE,gBAAgB,mBAAmB;AAErE,MAAK,wBAAW,MAAM,EAAE;AACtB,QAAM,4BAAM,OAAO,EAAE,WAAW,KAAM,EAAC,CAAC,MAAM,MAAM,CAAE,EAAC;AACvD,QAAM,2CAAqB,KAAK,CAAC,MAAM,MAAM,CAAE,EAAC;CAClD;AAEA,OAAM,QAAQ,WAAW,MAAM,QAAQ;AACzC"}
package/dist/kv/kv.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"kv.js","names":[],"sources":["../../src/kv/kv.ts"],"sourcesContent":["import { DatabaseSync, StatementSync } from 'node:sqlite';\nimport { deserializer, serializer } from './serde';\nimport { getNestedValue, setNestedValue } from './dotprops';\n\nexport type { SerializedValue } from './serde';\n\n/**\n * Configuration options for the KV store\n */\nexport interface KvOptions {\n /** Enable Write-Ahead Logging for better performance and durability */\n enableWAL?: boolean;\n /** Namespace for the key-value store table */\n namespace?: string;\n}\n\n/**\n * A key-value store implementation using SQLite\n *\n * This class provides a simple, persistent key-value storage solution\n * with support for namespaces, automatic cleanup, iteration, expiration, and JSON serialization.\n *\n * @example\n * ```typescript\n * const kv = new KV('data.db');\n *\n * // Store any JSON-serializable data\n * kv.set('user:123', { name: 'John', age: 30 });\n * kv.set('counter', 42);\n * kv.set('active', true);\n * kv.set('dates', [new Date(), new Date()]);\n *\n * // Use dot notation for nested properties\n * kv.set('user:123.name', 'John');\n * kv.set('user:123.settings.theme', 'dark');\n *\n * // Retrieve data\n * const user = kv.get('user:123'); // { name: 'John', age: 30, settings: { theme: 'dark' } }\n * const name = kv.get('user:123.name'); // 'John'\n * ```\n */\nexport class KV implements Disposable, AsyncDisposable {\n private db: DatabaseSync;\n private statements: Record<string, StatementSync> = {};\n\n /**\n * Creates a new KV store instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n */\n public constructor(\n path: string | Buffer | URL | DatabaseSync,\n private options: KvOptions = {\n enableWAL: true,\n namespace: 'commandkit_kv',\n },\n ) {\n this.db =\n path instanceof DatabaseSync\n ? path\n : new DatabaseSync(path, { open: true });\n\n if (options.enableWAL) {\n this.db.exec(/* sql */ `PRAGMA journal_mode = WAL;`);\n }\n\n const namespace = this.options.namespace ?? 'commandkit_kv';\n\n this.db.exec(/* sql */ `\n CREATE TABLE IF NOT EXISTS ${namespace} (\n key TEXT PRIMARY KEY,\n value TEXT,\n expires_at INTEGER\n )\n `);\n\n this.statements = {\n get: this.db.prepare(\n /* sql */ `SELECT value, expires_at FROM ${namespace} WHERE key = ?`,\n ),\n set: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ${namespace} (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n setex: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ${namespace} (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n delete: this.db.prepare(\n /* sql */ `DELETE FROM ${namespace} WHERE key = ?`,\n ),\n has: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ${namespace} WHERE key = ? AND (expires_at IS NULL OR expires_at > ?)`,\n ),\n keys: this.db.prepare(\n /* sql */ `SELECT key FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n values: this.db.prepare(\n /* sql */ `SELECT value FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n clear: this.db.prepare(/* sql */ `DELETE FROM ${namespace}`),\n count: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n all: this.db.prepare(\n /* sql */ `SELECT key, value FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n expire: this.db.prepare(\n /* sql */ `UPDATE ${namespace} SET expires_at = ? WHERE key = ?`,\n ),\n ttl: this.db.prepare(\n /* sql */ `SELECT expires_at FROM ${namespace} WHERE key = ?`,\n ),\n namespaces: this.db.prepare(\n /* sql */ `SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`,\n ),\n begin: this.db.prepare(/* sql */ `BEGIN TRANSACTION`),\n commit: this.db.prepare(/* sql */ `COMMIT`),\n rollback: this.db.prepare(/* sql */ `ROLLBACK`),\n };\n }\n\n /**\n * Gets the current timestamp in milliseconds\n */\n private getCurrentTime(): number {\n return Date.now();\n }\n\n /**\n * Checks if the database connection is open\n *\n * @returns `true` if the database is open, `false` otherwise\n */\n public isOpen(): boolean {\n return this.db.isOpen;\n }\n\n /**\n * Gets the underlying SQLite database instance\n *\n * @returns The DatabaseSync instance\n */\n public getDatabase(): DatabaseSync {\n return this.db;\n }\n\n /**\n * Closes the database connection\n */\n public close(): void {\n if (this.db.isOpen) this.db.close();\n }\n\n /**\n * Disposable implementation - closes the database when disposed\n */\n public [Symbol.dispose]() {\n this.close();\n }\n\n /**\n * AsyncDisposable implementation - closes the database when disposed\n */\n public async [Symbol.asyncDispose]() {\n this.close();\n }\n\n /**\n * Retrieves a value by key\n *\n * @param key - The key to retrieve (supports dot notation for nested properties)\n * @returns The value associated with the key, or `undefined` if not found or expired\n *\n * @example\n * ```typescript\n * // Store an object\n * kv.set('user:123', { name: 'John', age: 30, settings: { theme: 'dark' } });\n *\n * // Get the entire object\n * const user = kv.get('user:123');\n * // { name: 'John', age: 30, settings: { theme: 'dark' } }\n *\n * // Get nested properties using dot notation\n * const name = kv.get('user:123.name'); // 'John'\n * const theme = kv.get('user:123.settings.theme'); // 'dark'\n * ```\n */\n public get<T = any>(key: string): T | undefined {\n const result = this.statements.get.get(key);\n\n if (!result) return undefined;\n\n // Check if the key has expired\n if (\n result.expires_at &&\n Number(result.expires_at) <= this.getCurrentTime()\n ) {\n this.delete(key);\n return undefined;\n }\n\n const serialized = JSON.parse(result.value as string);\n const deserialized = deserializer(serialized);\n\n // Handle dot notation for nested properties\n if (key.includes('.')) {\n return getNestedValue(deserialized, key.split('.').slice(1).join('.'));\n }\n\n return deserialized;\n }\n\n /**\n * Sets a key-value pair\n *\n * @param key - The key to set (supports dot notation for nested properties)\n * @param value - The value to associate with the key (any JSON-serializable type)\n *\n * @example\n * ```typescript\n * // Store primitive values\n * kv.set('counter', 42);\n * kv.set('active', true);\n * kv.set('name', 'John');\n *\n * // Store objects\n * kv.set('user:123', { name: 'John', age: 30 });\n *\n * // Store arrays\n * kv.set('tags', ['javascript', 'typescript', 'sqlite']);\n *\n * // Store dates\n * kv.set('created', new Date());\n *\n * // Store maps and sets\n * kv.set('permissions', new Map([['admin', true], ['user', false]]));\n * kv.set('unique_ids', new Set([1, 2, 3, 4, 5]));\n *\n * // Use dot notation for nested properties\n * kv.set('user:123.settings.theme', 'dark');\n * kv.set('user:123.settings.notifications', true);\n * ```\n */\n public set(key: string, value: any): void {\n let serializedValue: string;\n\n if (key.includes('.')) {\n // Handle dot notation for nested properties\n const [baseKey, ...pathParts] = key.split('.');\n const path = pathParts.join('.');\n\n // Get existing value or create new object\n const existing = this.get(baseKey) || {};\n setNestedValue(existing, path, value);\n\n const serialized = serializer(existing);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.set.run(baseKey, serializedValue, null);\n } else {\n const serialized = serializer(value);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.set.run(key, serializedValue, null);\n }\n }\n\n /**\n * Sets a key-value pair with expiration\n *\n * @param key - The key to set (supports dot notation for nested properties)\n * @param value - The value to associate with the key (any JSON-serializable type)\n * @param ttl - Time to live in milliseconds\n *\n * @example\n * ```typescript\n * // Set with 1 hour expiration\n * kv.setex('session:123', { userId: 123, token: 'abc123' }, 60 * 60 * 1000);\n *\n * // Set with 5 minutes expiration\n * kv.setex('temp:data', { cached: true, timestamp: Date.now() }, 5 * 60 * 1000);\n *\n * // Use dot notation with expiration\n * kv.setex('user:123.temp_settings', { theme: 'light' }, 30 * 60 * 1000);\n * ```\n */\n public setex(key: string, value: any, ttl: number): void {\n const expiresAt = this.getCurrentTime() + ttl;\n let serializedValue: string;\n\n if (key.includes('.')) {\n // Handle dot notation for nested properties\n const [baseKey, ...pathParts] = key.split('.');\n const path = pathParts.join('.');\n\n // Get existing value or create new object\n const existing = this.get(baseKey) || {};\n setNestedValue(existing, path, value);\n\n const serialized = serializer(existing);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.setex.run(baseKey, serializedValue, expiresAt);\n } else {\n const serialized = serializer(value);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.setex.run(key, serializedValue, expiresAt);\n }\n }\n\n /**\n * Sets expiration for an existing key\n *\n * @param key - The key to set expiration for\n * @param ttl - Time to live in milliseconds\n * @returns `true` if the key exists and expiration was set, `false` otherwise\n *\n * @example\n * ```typescript\n * kv.set('user:123', { name: 'John', age: 30 });\n *\n * // Set 30 minute expiration\n * if (kv.expire('user:123', 30 * 60 * 1000)) {\n * console.log('Expiration set successfully');\n * }\n * ```\n */\n public expire(key: string, ttl: number): boolean {\n if (!this.has(key)) return false;\n\n const expiresAt = this.getCurrentTime() + ttl;\n this.statements.expire.run(expiresAt, key);\n return true;\n }\n\n /**\n * Gets the time to live for a key\n *\n * @param key - The key to check\n * @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration\n *\n * @example\n * ```typescript\n * const ttl = kv.ttl('user:123');\n * if (ttl > 0) {\n * console.log(`Key expires in ${ttl}ms`);\n * } else if (ttl === -2) {\n * console.log('Key has no expiration');\n * } else {\n * console.log('Key does not exist');\n * }\n * ```\n */\n public ttl(key: string): number {\n const result = this.statements.ttl.get(key);\n\n if (!result) return -1; // Key doesn't exist\n\n if (!result.expires_at) return -2; // No expiration\n\n const remaining = Number(result.expires_at) - this.getCurrentTime();\n return remaining > 0 ? remaining : -1; // Expired or doesn't exist\n }\n\n /**\n * Deletes a key-value pair\n *\n * @param key - The key to delete\n *\n * @example\n * ```typescript\n * kv.delete('user:123');\n * kv.delete('user:123.settings.theme'); // Delete nested property\n * ```\n */\n public delete(key: string): void {\n this.statements.delete.run(key);\n }\n\n /**\n * Checks if a key exists and is not expired\n *\n * @param key - The key to check\n * @returns `true` if the key exists and is not expired, `false` otherwise\n *\n * @example\n * ```typescript\n * if (kv.has('user:123')) {\n * console.log('User exists and is not expired');\n * }\n *\n * if (kv.has('user:123.settings.theme')) {\n * console.log('Theme setting exists');\n * }\n * ```\n */\n public has(key: string): boolean {\n const result = this.statements.has.get(key, this.getCurrentTime());\n\n return (\n result?.count !== undefined &&\n result.count !== null &&\n Number(result.count) > 0\n );\n }\n\n /**\n * Gets all keys in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired keys\n *\n * @example\n * ```typescript\n * const keys = kv.keys();\n * console.log('All keys:', keys);\n * ```\n */\n public keys(): string[] {\n const result = this.statements.keys.all(this.getCurrentTime());\n\n return result.map((row) => row.key as string);\n }\n\n /**\n * Gets all values in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired values\n *\n * @example\n * ```typescript\n * const values = kv.values();\n * console.log('All values:', values);\n * ```\n */\n public values(): any[] {\n const result = this.statements.values.all(this.getCurrentTime());\n\n return result.map((row) => {\n const serialized = JSON.parse(row.value as string);\n return deserializer(serialized);\n });\n }\n\n /**\n * Gets the total number of key-value pairs in the current namespace (excluding expired keys)\n *\n * @returns The count of non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const count = kv.count();\n * console.log(`Total entries: ${count}`);\n * ```\n */\n public count(): number {\n const result = this.statements.count.get(this.getCurrentTime());\n\n return Number(result?.count ?? 0);\n }\n\n /**\n * Removes all key-value pairs from the current namespace\n *\n * @example\n * ```typescript\n * kv.clear(); // Removes all entries in current namespace\n * ```\n */\n public clear(): void {\n this.statements.clear.run();\n }\n\n /**\n * Gets all key-value pairs as an object (excluding expired keys)\n *\n * @returns Object with all non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const all = kv.all();\n * console.log('All entries:', all);\n * // Output: { 'key1': value1, 'key2': value2 }\n * ```\n */\n public all(): Record<string, any> {\n const result = this.statements.all.all(this.getCurrentTime());\n\n return Object.fromEntries(\n result.map((row) => {\n const serialized = JSON.parse(row.value as string);\n return [row.key as string, deserializer(serialized)];\n }),\n );\n }\n\n /**\n * Gets all available namespaces (tables) in the database\n *\n * @returns Array of namespace names\n *\n * @example\n * ```typescript\n * const namespaces = kv.namespaces();\n * console.log('Available namespaces:', namespaces);\n * ```\n */\n public namespaces(): string[] {\n const result = this.statements.namespaces.all();\n\n return result.map((row) => row.name as string);\n }\n\n /**\n * Gets the current namespace name\n *\n * @returns The current namespace string\n */\n public getCurrentNamespace(): string {\n return this.options.namespace ?? 'commandkit_kv';\n }\n\n /**\n * Creates a new KV instance with a different namespace\n *\n * @param namespace - The namespace to use for the new instance\n * @returns A new KV instance with the specified namespace\n *\n * @example\n * ```typescript\n * const userKv = kv.namespace('users');\n * const configKv = kv.namespace('config');\n *\n * userKv.set('123', { name: 'John', age: 30 });\n * configKv.set('theme', 'dark');\n * ```\n */\n public namespace(namespace: string): KV {\n return new KV(this.db, {\n enableWAL: this.options.enableWAL,\n namespace,\n });\n }\n\n /**\n * Iterator implementation for iterating over all non-expired key-value pairs\n *\n * @returns Iterator yielding [key, value] tuples\n *\n * @example\n * ```typescript\n * for (const [key, value] of kv) {\n * console.log(`${key}:`, value);\n * }\n *\n * // Or using spread operator\n * const entries = [...kv];\n * ```\n */\n public *[Symbol.iterator](): Iterator<[string, any]> {\n const result = this.statements.all.iterate(this.getCurrentTime());\n\n for (const row of result) {\n const serialized = JSON.parse(row.value as string);\n yield [row.key as string, deserializer(serialized)];\n }\n }\n\n /**\n * Executes a function within a transaction\n *\n * @param fn - Function to execute within the transaction (can be async)\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * // Synchronous transaction\n * kv.transaction(() => {\n * kv.set('user:123', { name: 'John', age: 30 });\n * kv.set('user:456', { name: 'Jane', age: 25 });\n * // If any operation fails, all changes are rolled back\n * });\n *\n * // Async transaction\n * await kv.transaction(async () => {\n * kv.set('user:123', { name: 'John', age: 30 });\n * await someAsyncOperation();\n * kv.set('user:456', { name: 'Jane', age: 25 });\n * // If any operation fails, all changes are rolled back\n * });\n * ```\n */\n public async transaction<T>(fn: () => T | Promise<T>): Promise<T> {\n try {\n // Begin transaction\n this.statements.begin.run();\n\n // Execute the function\n const result = await fn();\n\n // Commit transaction\n this.statements.commit.run();\n\n return result;\n } catch (error) {\n // Rollback transaction on error\n this.statements.rollback.run();\n throw error;\n }\n }\n}\n\n/**\n * Opens a new KV instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n * @returns A new KV instance\n */\nexport function openKV(\n path: string | Buffer | URL | DatabaseSync = 'commandkit_kv.db',\n options: KvOptions = { enableWAL: true, namespace: 'commandkit_kv' },\n): KV {\n return new KV(path, options);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"kv.js","names":[],"sources":["../../src/kv/kv.ts"],"sourcesContent":["import { DatabaseSync, StatementSync } from 'node:sqlite';\nimport { deserializer, serializer } from './serde';\nimport { getNestedValue, setNestedValue } from './dotprops';\n\nexport type { SerializedValue } from './serde';\n\n/**\n * Configuration options for the KV store\n */\nexport interface KvOptions {\n /** Enable Write-Ahead Logging for better performance and durability */\n enableWAL?: boolean;\n /** Namespace for the key-value store table */\n namespace?: string;\n}\n\n/**\n * A key-value store implementation using SQLite\n *\n * This class provides a simple, persistent key-value storage solution\n * with support for namespaces, automatic cleanup, iteration, expiration, and JSON serialization.\n *\n * @example\n * ```typescript\n * const kv = new KV('data.db');\n *\n * // Store any JSON-serializable data\n * kv.set('user:123', { name: 'John', age: 30 });\n * kv.set('counter', 42);\n * kv.set('active', true);\n * kv.set('dates', [new Date(), new Date()]);\n *\n * // Use dot notation for nested properties\n * kv.set('user:123.name', 'John');\n * kv.set('user:123.settings.theme', 'dark');\n *\n * // Retrieve data\n * const user = kv.get('user:123'); // { name: 'John', age: 30, settings: { theme: 'dark' } }\n * const name = kv.get('user:123.name'); // 'John'\n * ```\n */\nexport class KV implements Disposable, AsyncDisposable {\n private db: DatabaseSync;\n private statements: Record<string, StatementSync> = {};\n\n /**\n * Creates a new KV store instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n */\n public constructor(\n path: string | Buffer | URL | DatabaseSync,\n private options: KvOptions = {\n enableWAL: true,\n namespace: 'commandkit_kv',\n },\n ) {\n this.db =\n path instanceof DatabaseSync\n ? path\n : new DatabaseSync(path, { open: true });\n\n if (options.enableWAL) {\n this.db.exec(/* sql */ `PRAGMA journal_mode = WAL;`);\n }\n\n const namespace = this.options.namespace ?? 'commandkit_kv';\n\n this.db.exec(/* sql */ `\n CREATE TABLE IF NOT EXISTS ${namespace} (\n key TEXT PRIMARY KEY,\n value TEXT,\n expires_at INTEGER\n )\n `);\n\n this.statements = {\n get: this.db.prepare(\n /* sql */ `SELECT value, expires_at FROM ${namespace} WHERE key = ?`,\n ),\n set: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ${namespace} (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n setex: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ${namespace} (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n delete: this.db.prepare(\n /* sql */ `DELETE FROM ${namespace} WHERE key = ?`,\n ),\n has: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ${namespace} WHERE key = ? AND (expires_at IS NULL OR expires_at > ?)`,\n ),\n keys: this.db.prepare(\n /* sql */ `SELECT key FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n values: this.db.prepare(\n /* sql */ `SELECT value FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n clear: this.db.prepare(/* sql */ `DELETE FROM ${namespace}`),\n count: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n all: this.db.prepare(\n /* sql */ `SELECT key, value FROM ${namespace} WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n expire: this.db.prepare(\n /* sql */ `UPDATE ${namespace} SET expires_at = ? WHERE key = ?`,\n ),\n ttl: this.db.prepare(\n /* sql */ `SELECT expires_at FROM ${namespace} WHERE key = ?`,\n ),\n namespaces: this.db.prepare(\n /* sql */ `SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`,\n ),\n begin: this.db.prepare(/* sql */ `BEGIN TRANSACTION`),\n commit: this.db.prepare(/* sql */ `COMMIT`),\n rollback: this.db.prepare(/* sql */ `ROLLBACK`),\n };\n }\n\n /**\n * Gets the current timestamp in milliseconds\n */\n private getCurrentTime(): number {\n return Date.now();\n }\n\n /**\n * Checks if the database connection is open\n *\n * @returns `true` if the database is open, `false` otherwise\n */\n public isOpen(): boolean {\n return this.db.isOpen;\n }\n\n /**\n * Gets the underlying SQLite database instance\n *\n * @returns The DatabaseSync instance\n */\n public getDatabase(): DatabaseSync {\n return this.db;\n }\n\n /**\n * Closes the database connection\n */\n public close(): void {\n if (this.db.isOpen) this.db.close();\n }\n\n /**\n * Disposable implementation - closes the database when disposed\n */\n public [Symbol.dispose]() {\n this.close();\n }\n\n /**\n * AsyncDisposable implementation - closes the database when disposed\n */\n public async [Symbol.asyncDispose]() {\n this.close();\n }\n\n /**\n * Retrieves a value by key\n *\n * @param key - The key to retrieve (supports dot notation for nested properties)\n * @returns The value associated with the key, or `undefined` if not found or expired\n *\n * @example\n * ```typescript\n * // Store an object\n * kv.set('user:123', { name: 'John', age: 30, settings: { theme: 'dark' } });\n *\n * // Get the entire object\n * const user = kv.get('user:123');\n * // { name: 'John', age: 30, settings: { theme: 'dark' } }\n *\n * // Get nested properties using dot notation\n * const name = kv.get('user:123.name'); // 'John'\n * const theme = kv.get('user:123.settings.theme'); // 'dark'\n * ```\n */\n public get<T = any>(key: string): T | undefined {\n const result = this.statements.get.get(key);\n\n if (!result) return undefined;\n\n // Check if the key has expired\n if (\n result.expires_at &&\n Number(result.expires_at) <= this.getCurrentTime()\n ) {\n this.delete(key);\n return undefined;\n }\n\n const serialized = JSON.parse(result.value as string);\n const deserialized = deserializer(serialized);\n\n // Handle dot notation for nested properties\n if (key.includes('.')) {\n return getNestedValue(deserialized, key.split('.').slice(1).join('.'));\n }\n\n return deserialized;\n }\n\n /**\n * Sets a key-value pair\n *\n * @param key - The key to set (supports dot notation for nested properties)\n * @param value - The value to associate with the key (any JSON-serializable type)\n *\n * @example\n * ```typescript\n * // Store primitive values\n * kv.set('counter', 42);\n * kv.set('active', true);\n * kv.set('name', 'John');\n *\n * // Store objects\n * kv.set('user:123', { name: 'John', age: 30 });\n *\n * // Store arrays\n * kv.set('tags', ['javascript', 'typescript', 'sqlite']);\n *\n * // Store dates\n * kv.set('created', new Date());\n *\n * // Store maps and sets\n * kv.set('permissions', new Map([['admin', true], ['user', false]]));\n * kv.set('unique_ids', new Set([1, 2, 3, 4, 5]));\n *\n * // Use dot notation for nested properties\n * kv.set('user:123.settings.theme', 'dark');\n * kv.set('user:123.settings.notifications', true);\n * ```\n */\n public set(key: string, value: any): void {\n let serializedValue: string;\n\n if (key.includes('.')) {\n // Handle dot notation for nested properties\n const [baseKey, ...pathParts] = key.split('.');\n const path = pathParts.join('.');\n\n // Get existing value or create new object\n const existing = this.get(baseKey) || {};\n setNestedValue(existing, path, value);\n\n const serialized = serializer(existing);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.set.run(baseKey, serializedValue, null);\n } else {\n const serialized = serializer(value);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.set.run(key, serializedValue, null);\n }\n }\n\n /**\n * Sets a key-value pair with expiration\n *\n * @param key - The key to set (supports dot notation for nested properties)\n * @param value - The value to associate with the key (any JSON-serializable type)\n * @param ttl - Time to live in milliseconds\n *\n * @example\n * ```typescript\n * // Set with 1 hour expiration\n * kv.setex('session:123', { userId: 123, token: 'abc123' }, 60 * 60 * 1000);\n *\n * // Set with 5 minutes expiration\n * kv.setex('temp:data', { cached: true, timestamp: Date.now() }, 5 * 60 * 1000);\n *\n * // Use dot notation with expiration\n * kv.setex('user:123.temp_settings', { theme: 'light' }, 30 * 60 * 1000);\n * ```\n */\n public setex(key: string, value: any, ttl: number): void {\n const expiresAt = this.getCurrentTime() + ttl;\n let serializedValue: string;\n\n if (key.includes('.')) {\n // Handle dot notation for nested properties\n const [baseKey, ...pathParts] = key.split('.');\n const path = pathParts.join('.');\n\n // Get existing value or create new object\n const existing = this.get(baseKey) || {};\n setNestedValue(existing, path, value);\n\n const serialized = serializer(existing);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.setex.run(baseKey, serializedValue, expiresAt);\n } else {\n const serialized = serializer(value);\n serializedValue = JSON.stringify(serialized);\n\n this.statements.setex.run(key, serializedValue, expiresAt);\n }\n }\n\n /**\n * Sets expiration for an existing key\n *\n * @param key - The key to set expiration for\n * @param ttl - Time to live in milliseconds\n * @returns `true` if the key exists and expiration was set, `false` otherwise\n *\n * @example\n * ```typescript\n * kv.set('user:123', { name: 'John', age: 30 });\n *\n * // Set 30 minute expiration\n * if (kv.expire('user:123', 30 * 60 * 1000)) {\n * console.log('Expiration set successfully');\n * }\n * ```\n */\n public expire(key: string, ttl: number): boolean {\n if (!this.has(key)) return false;\n\n const expiresAt = this.getCurrentTime() + ttl;\n this.statements.expire.run(expiresAt, key);\n return true;\n }\n\n /**\n * Gets the time to live for a key\n *\n * @param key - The key to check\n * @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration\n *\n * @example\n * ```typescript\n * const ttl = kv.ttl('user:123');\n * if (ttl > 0) {\n * console.log(`Key expires in ${ttl}ms`);\n * } else if (ttl === -2) {\n * console.log('Key has no expiration');\n * } else {\n * console.log('Key does not exist');\n * }\n * ```\n */\n public ttl(key: string): number {\n const result = this.statements.ttl.get(key);\n\n if (!result) return -1; // Key doesn't exist\n\n if (!result.expires_at) return -2; // No expiration\n\n const remaining = Number(result.expires_at) - this.getCurrentTime();\n return remaining > 0 ? remaining : -1; // Expired or doesn't exist\n }\n\n /**\n * Deletes a key-value pair\n *\n * @param key - The key to delete\n *\n * @example\n * ```typescript\n * kv.delete('user:123');\n * kv.delete('user:123.settings.theme'); // Delete nested property\n * ```\n */\n public delete(key: string): void {\n this.statements.delete.run(key);\n }\n\n /**\n * Checks if a key exists and is not expired\n *\n * @param key - The key to check\n * @returns `true` if the key exists and is not expired, `false` otherwise\n *\n * @example\n * ```typescript\n * if (kv.has('user:123')) {\n * console.log('User exists and is not expired');\n * }\n *\n * if (kv.has('user:123.settings.theme')) {\n * console.log('Theme setting exists');\n * }\n * ```\n */\n public has(key: string): boolean {\n const result = this.statements.has.get(key, this.getCurrentTime());\n\n return (\n result?.count !== undefined &&\n result.count !== null &&\n Number(result.count) > 0\n );\n }\n\n /**\n * Gets all keys in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired keys\n *\n * @example\n * ```typescript\n * const keys = kv.keys();\n * console.log('All keys:', keys);\n * ```\n */\n public keys(): string[] {\n const result = this.statements.keys.all(this.getCurrentTime());\n\n return result.map((row) => row.key as string);\n }\n\n /**\n * Gets all values in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired values\n *\n * @example\n * ```typescript\n * const values = kv.values();\n * console.log('All values:', values);\n * ```\n */\n public values(): any[] {\n const result = this.statements.values.all(this.getCurrentTime());\n\n return result.map((row) => {\n const serialized = JSON.parse(row.value as string);\n return deserializer(serialized);\n });\n }\n\n /**\n * Gets the total number of key-value pairs in the current namespace (excluding expired keys)\n *\n * @returns The count of non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const count = kv.count();\n * console.log(`Total entries: ${count}`);\n * ```\n */\n public count(): number {\n const result = this.statements.count.get(this.getCurrentTime());\n\n return Number(result?.count ?? 0);\n }\n\n /**\n * Removes all key-value pairs from the current namespace\n *\n * @example\n * ```typescript\n * kv.clear(); // Removes all entries in current namespace\n * ```\n */\n public clear(): void {\n this.statements.clear.run();\n }\n\n /**\n * Gets all key-value pairs as an object (excluding expired keys)\n *\n * @returns Object with all non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const all = kv.all();\n * console.log('All entries:', all);\n * // Output: { 'key1': value1, 'key2': value2 }\n * ```\n */\n public all(): Record<string, any> {\n const result = this.statements.all.all(this.getCurrentTime());\n\n return Object.fromEntries(\n result.map((row) => {\n const serialized = JSON.parse(row.value as string);\n return [row.key as string, deserializer(serialized)];\n }),\n );\n }\n\n /**\n * Gets all available namespaces (tables) in the database\n *\n * @returns Array of namespace names\n *\n * @example\n * ```typescript\n * const namespaces = kv.namespaces();\n * console.log('Available namespaces:', namespaces);\n * ```\n */\n public namespaces(): string[] {\n const result = this.statements.namespaces.all();\n\n return result.map((row) => row.name as string);\n }\n\n /**\n * Gets the current namespace name\n *\n * @returns The current namespace string\n */\n public getCurrentNamespace(): string {\n return this.options.namespace ?? 'commandkit_kv';\n }\n\n /**\n * Creates a new KV instance with a different namespace\n *\n * @param namespace - The namespace to use for the new instance\n * @returns A new KV instance with the specified namespace\n *\n * @example\n * ```typescript\n * const userKv = kv.namespace('users');\n * const configKv = kv.namespace('config');\n *\n * userKv.set('123', { name: 'John', age: 30 });\n * configKv.set('theme', 'dark');\n * ```\n */\n public namespace(namespace: string): KV {\n return new KV(this.db, {\n enableWAL: this.options.enableWAL,\n namespace,\n });\n }\n\n /**\n * Iterator implementation for iterating over all non-expired key-value pairs\n *\n * @returns Iterator yielding [key, value] tuples\n *\n * @example\n * ```typescript\n * for (const [key, value] of kv) {\n * console.log(`${key}:`, value);\n * }\n *\n * // Or using spread operator\n * const entries = [...kv];\n * ```\n */\n public *[Symbol.iterator](): Iterator<[string, any]> {\n const result = this.statements.all.iterate(this.getCurrentTime());\n\n for (const row of result) {\n const serialized = JSON.parse(row.value as string);\n yield [row.key as string, deserializer(serialized)];\n }\n }\n\n /**\n * Executes a function within a transaction\n *\n * @param fn - Function to execute within the transaction (can be async)\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * // Synchronous transaction\n * kv.transaction(() => {\n * kv.set('user:123', { name: 'John', age: 30 });\n * kv.set('user:456', { name: 'Jane', age: 25 });\n * // If any operation fails, all changes are rolled back\n * });\n *\n * // Async transaction\n * await kv.transaction(async () => {\n * kv.set('user:123', { name: 'John', age: 30 });\n * await someAsyncOperation();\n * kv.set('user:456', { name: 'Jane', age: 25 });\n * // If any operation fails, all changes are rolled back\n * });\n * ```\n */\n public async transaction<T>(fn: () => T | Promise<T>): Promise<T> {\n try {\n // Begin transaction\n this.statements.begin.run();\n\n // Execute the function\n const result = await fn();\n\n // Commit transaction\n this.statements.commit.run();\n\n return result;\n } catch (error) {\n // Rollback transaction on error\n this.statements.rollback.run();\n throw error;\n }\n }\n}\n\n/**\n * Opens a new KV instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n * @returns A new KV instance\n */\nexport function openKV(\n path: string | Buffer | URL | DatabaseSync = 'commandkit_kv.db',\n options: KvOptions = { enableWAL: true, namespace: 'commandkit_kv' },\n): KV {\n return new KV(path, options);\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  require('../colors-Cd4Oz-r-.js');
2
2
  require('../ActionRow-CmTHbo2t.js');
3
- require('../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
3
+ require('../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../CommandKit-DuH9iT2t.js');
5
5
  require('../common-CcfjYnPG.js');
6
6
  require('../common-vnMIelAE.js');
7
7
  require('../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../runtime-5fxB4uhe.js');
23
23
  require('../resolve-file-url-9aPt6A_n.js');
24
24
  require('../types-package-MDczrp9f.js');
25
25
  require('../EventWorkerContext-DxfS_0fJ.js');
26
- require('../signals-lSAO5hOr.js');
26
+ require('../signals-Bu7gndaS.js');
27
27
  require('../constants-R96vEAFD.js');
28
- require('../MessageCommandParser-CUZrGknY.js');
28
+ require('../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../CommandsRouter-Bs9UuowL.js');
30
30
  require('../EventsRouter-B7oifgM6.js');
31
31
  require('../router-wA3kFzES.js');
@@ -1,7 +1,7 @@
1
1
  require('../colors-Cd4Oz-r-.js');
2
2
  require('../ActionRow-CmTHbo2t.js');
3
- require('../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
3
+ require('../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../CommandKit-DuH9iT2t.js');
5
5
  require('../common-CcfjYnPG.js');
6
6
  require('../common-vnMIelAE.js');
7
7
  require('../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../runtime-5fxB4uhe.js');
23
23
  require('../resolve-file-url-9aPt6A_n.js');
24
24
  require('../types-package-MDczrp9f.js');
25
25
  require('../EventWorkerContext-DxfS_0fJ.js');
26
- require('../signals-lSAO5hOr.js');
26
+ require('../signals-Bu7gndaS.js');
27
27
  require('../constants-R96vEAFD.js');
28
- require('../MessageCommandParser-CUZrGknY.js');
28
+ require('../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../CommandsRouter-Bs9UuowL.js');
30
30
  require('../EventsRouter-B7oifgM6.js');
31
31
  require('../router-wA3kFzES.js');
@@ -1,7 +1,7 @@
1
1
  require('../colors-Cd4Oz-r-.js');
2
2
  require('../ActionRow-CmTHbo2t.js');
3
- require('../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
3
+ require('../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../CommandKit-DuH9iT2t.js');
5
5
  require('../common-CcfjYnPG.js');
6
6
  require('../common-vnMIelAE.js');
7
7
  require('../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../runtime-5fxB4uhe.js');
23
23
  require('../resolve-file-url-9aPt6A_n.js');
24
24
  require('../types-package-MDczrp9f.js');
25
25
  require('../EventWorkerContext-DxfS_0fJ.js');
26
- require('../signals-lSAO5hOr.js');
26
+ require('../signals-Bu7gndaS.js');
27
27
  require('../constants-R96vEAFD.js');
28
- require('../MessageCommandParser-CUZrGknY.js');
28
+ require('../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../CommandsRouter-Bs9UuowL.js');
30
30
  require('../EventsRouter-B7oifgM6.js');
31
31
  require('../router-wA3kFzES.js');
@@ -1,7 +1,7 @@
1
1
  require('../../colors-Cd4Oz-r-.js');
2
2
  require('../../ActionRow-CmTHbo2t.js');
3
- require('../../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../../CommandKit-DkPVD3wV.js');
3
+ require('../../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../../CommandKit-DuH9iT2t.js');
5
5
  require('../../common-CcfjYnPG.js');
6
6
  require('../../common-vnMIelAE.js');
7
7
  require('../../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../../runtime-5fxB4uhe.js');
23
23
  require('../../resolve-file-url-9aPt6A_n.js');
24
24
  require('../../types-package-MDczrp9f.js');
25
25
  require('../../EventWorkerContext-DxfS_0fJ.js');
26
- require('../../signals-lSAO5hOr.js');
26
+ require('../../signals-Bu7gndaS.js');
27
27
  require('../../constants-R96vEAFD.js');
28
- require('../../MessageCommandParser-CUZrGknY.js');
28
+ require('../../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../../CommandsRouter-Bs9UuowL.js');
30
30
  require('../../EventsRouter-B7oifgM6.js');
31
31
  require('../../router-wA3kFzES.js');
@@ -1,7 +1,7 @@
1
1
  require('../../colors-Cd4Oz-r-.js');
2
2
  require('../../ActionRow-CmTHbo2t.js');
3
- require('../../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../../CommandKit-DkPVD3wV.js');
3
+ require('../../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../../CommandKit-DuH9iT2t.js');
5
5
  require('../../common-CcfjYnPG.js');
6
6
  require('../../common-vnMIelAE.js');
7
7
  require('../../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../../runtime-5fxB4uhe.js');
23
23
  require('../../resolve-file-url-9aPt6A_n.js');
24
24
  require('../../types-package-MDczrp9f.js');
25
25
  require('../../EventWorkerContext-DxfS_0fJ.js');
26
- require('../../signals-lSAO5hOr.js');
26
+ require('../../signals-Bu7gndaS.js');
27
27
  require('../../constants-R96vEAFD.js');
28
- require('../../MessageCommandParser-CUZrGknY.js');
28
+ require('../../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../../CommandsRouter-Bs9UuowL.js');
30
30
  require('../../EventsRouter-B7oifgM6.js');
31
31
  require('../../router-wA3kFzES.js');
@@ -1,7 +1,7 @@
1
1
  require('../../../colors-Cd4Oz-r-.js');
2
2
  require('../../../ActionRow-CmTHbo2t.js');
3
- require('../../../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../../../CommandKit-DkPVD3wV.js');
3
+ require('../../../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../../../CommandKit-DuH9iT2t.js');
5
5
  require('../../../common-CcfjYnPG.js');
6
6
  require('../../../common-vnMIelAE.js');
7
7
  require('../../../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../../../runtime-5fxB4uhe.js');
23
23
  require('../../../resolve-file-url-9aPt6A_n.js');
24
24
  require('../../../types-package-MDczrp9f.js');
25
25
  require('../../../EventWorkerContext-DxfS_0fJ.js');
26
- require('../../../signals-lSAO5hOr.js');
26
+ require('../../../signals-Bu7gndaS.js');
27
27
  require('../../../constants-R96vEAFD.js');
28
- require('../../../MessageCommandParser-CUZrGknY.js');
28
+ require('../../../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../../../CommandsRouter-Bs9UuowL.js');
30
30
  require('../../../EventsRouter-B7oifgM6.js');
31
31
  require('../../../router-wA3kFzES.js');
@@ -1,7 +1,7 @@
1
1
  require('../../../colors-Cd4Oz-r-.js');
2
2
  require('../../../ActionRow-CmTHbo2t.js');
3
- require('../../../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../../../CommandKit-DkPVD3wV.js');
3
+ require('../../../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../../../CommandKit-DuH9iT2t.js');
5
5
  require('../../../common-CcfjYnPG.js');
6
6
  require('../../../common-vnMIelAE.js');
7
7
  require('../../../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../../../runtime-5fxB4uhe.js');
23
23
  require('../../../resolve-file-url-9aPt6A_n.js');
24
24
  require('../../../types-package-MDczrp9f.js');
25
25
  require('../../../EventWorkerContext-DxfS_0fJ.js');
26
- require('../../../signals-lSAO5hOr.js');
26
+ require('../../../signals-Bu7gndaS.js');
27
27
  require('../../../constants-R96vEAFD.js');
28
- require('../../../MessageCommandParser-CUZrGknY.js');
28
+ require('../../../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../../../CommandsRouter-Bs9UuowL.js');
30
30
  require('../../../EventsRouter-B7oifgM6.js');
31
31
  require('../../../router-wA3kFzES.js');
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-file-url-9aPt6A_n.js","names":[],"sources":["../src/utils/resolve-file-url.ts"],"sourcesContent":["import path from 'path';\n\n/**\n * Convert a local file path to a file URL.\n * @param filePath - The local file's path.\n * @param withTs - Whether to append a timestamp to the URL.\n * @returns - The converted file URL.\n */\nexport function toFileURL(filePath: string, withTs = false) {\n const resolvedPath = path.resolve(filePath);\n return `${'file://' + resolvedPath.replace(/\\\\\\\\|\\\\/g, '/')}${withTs ? `?ts=${Date.now()}` : ''}`;\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAgB,UAAU,UAAkB,SAAS,OAAO;CAC1D,MAAM,eAAe,aAAK,QAAQ,SAAS;AAC3C,SAAQ,EAAE,YAAY,aAAa,QAAQ,YAAY,IAAI,CAAC,EAAE,UAAU,MAAM,KAAK,KAAK,CAAC,IAAI,GAAG;AAClG"}
1
+ {"version":3,"file":"resolve-file-url-9aPt6A_n.js","names":[],"sources":["../src/utils/resolve-file-url.ts"],"sourcesContent":["import path from 'path';\n\n/**\n * Convert a local file path to a file URL.\n * @param filePath - The local file's path.\n * @param withTs - Whether to append a timestamp to the URL.\n * @returns - The converted file URL.\n */\nexport function toFileURL(filePath: string, withTs = false) {\n const resolvedPath = path.resolve(filePath);\n return `${'file://' + resolvedPath.replace(/\\\\\\\\|\\\\/g, '/')}${withTs ? `?ts=${Date.now()}` : ''}`;\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAgB,UAAU,UAAkB,SAAS,OAAO;CAC1D,MAAM,eAAe,aAAK,QAAQ,SAAS;AAC3C,WAAU,YAAY,aAAa,QAAQ,YAAY,IAAI,GAAG,UAAU,MAAM,KAAK,KAAK,KAAK;AAC/F"}
@@ -1,4 +1,4 @@
1
- const require_error_codes = require('./error-codes-DXOuid4c.js');
1
+ const require_error_codes = require('./error-codes-C-ViHyu-.js');
2
2
  const require_EventWorkerContext = require('./EventWorkerContext-DxfS_0fJ.js');
3
3
 
4
4
  //#region src/app/interrupt/signals.ts
@@ -74,4 +74,4 @@ Object.defineProperty(exports, 'stopEvents', {
74
74
  return stopEvents;
75
75
  }
76
76
  });
77
- //# sourceMappingURL=signals-lSAO5hOr.js.map
77
+ //# sourceMappingURL=signals-Bu7gndaS.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals-lSAO5hOr.js","names":[],"sources":["../src/app/interrupt/signals.ts"],"sourcesContent":["import {\n CommandKitErrorCodes,\n createCommandKitError,\n isCommandKitError,\n} from '../../utils/error-codes';\nimport { eventWorkerContext } from '../events/EventWorkerContext';\n\n/**\n * Cancel upcoming middleware execution.\n * If this is called inside pre-stage middleware, the next run will be the actual command, skipping all other pre-stage middlewares.\n * If this is called inside a command itself, it will skip all post-stage middlewares.\n * If this is called inside post-stage middleware, it will skip all other post-stage middlewares.\n */\nexport function exitMiddleware(): never {\n throw createCommandKitError(CommandKitErrorCodes.ExitMiddleware);\n}\n\n/**\n * Rethrow the error if it is a CommandKit error.\n * @param error The error to rethrow.\n * @example try {\n * doSomething();\n * } catch(e) {\n * // do something\n *\n * // throw the error if it's a commandkit error\n * rethrow(e)\n * }\n */\nexport function rethrow(error: unknown): void {\n if (isCommandKitError(error)) throw error;\n}\n\n/**\n * Stops current command assuming it has been redirected to another command.\n */\nexport function redirect(): never {\n throw createCommandKitError(CommandKitErrorCodes.ForwardedCommand);\n}\n\n/**\n * Stops event propagation. This function should be called inside an event handler\n * to prevent further event handling.\n * @example // src/app/events/messageCreate/handler.ts\n * import { stopEvents } from 'commandkit';\n *\n * export default async function messageCreateHandler() {\n * console.log('Message created');\n * // Stop further event propagation\n * stopEvents();\n * }\n */\nexport function stopEvents(): never {\n if (!eventWorkerContext.getStore()) {\n throw new Error('stopEvents() may only be called inside an event handler');\n }\n\n throw createCommandKitError(CommandKitErrorCodes.StopEvents);\n}\n"],"mappings":";;;;;;;;;;AAaA,SAAgB,iBAAwB;AACtC,OAAM,0CAAsB,yCAAqB,eAAe;AAClE;;;;;;;;;;;;;AAcA,SAAgB,QAAQ,OAAsB;AAC5C,KAAI,sCAAkB,MAAM,CAAE,OAAM;AACtC;;;;AAKA,SAAgB,WAAkB;AAChC,OAAM,0CAAsB,yCAAqB,iBAAiB;AACpE;;;;;;;;;;;;;AAcA,SAAgB,aAAoB;AAClC,MAAK,8CAAmB,UAAU,CAChC,OAAM,IAAI,MAAM;AAGlB,OAAM,0CAAsB,yCAAqB,WAAW;AAC9D"}
1
+ {"version":3,"file":"signals-Bu7gndaS.js","names":[],"sources":["../src/app/interrupt/signals.ts"],"sourcesContent":["import {\n CommandKitErrorCodes,\n createCommandKitError,\n isCommandKitError,\n} from '../../utils/error-codes';\nimport { eventWorkerContext } from '../events/EventWorkerContext';\n\n/**\n * Cancel upcoming middleware execution.\n * If this is called inside pre-stage middleware, the next run will be the actual command, skipping all other pre-stage middlewares.\n * If this is called inside a command itself, it will skip all post-stage middlewares.\n * If this is called inside post-stage middleware, it will skip all other post-stage middlewares.\n */\nexport function exitMiddleware(): never {\n throw createCommandKitError(CommandKitErrorCodes.ExitMiddleware);\n}\n\n/**\n * Rethrow the error if it is a CommandKit error.\n * @param error The error to rethrow.\n * @example try {\n * doSomething();\n * } catch(e) {\n * // do something\n *\n * // throw the error if it's a commandkit error\n * rethrow(e)\n * }\n */\nexport function rethrow(error: unknown): void {\n if (isCommandKitError(error)) throw error;\n}\n\n/**\n * Stops current command assuming it has been redirected to another command.\n */\nexport function redirect(): never {\n throw createCommandKitError(CommandKitErrorCodes.ForwardedCommand);\n}\n\n/**\n * Stops event propagation. This function should be called inside an event handler\n * to prevent further event handling.\n * @example // src/app/events/messageCreate/handler.ts\n * import { stopEvents } from 'commandkit';\n *\n * export default async function messageCreateHandler() {\n * console.log('Message created');\n * // Stop further event propagation\n * stopEvents();\n * }\n */\nexport function stopEvents(): never {\n if (!eventWorkerContext.getStore()) {\n throw new Error('stopEvents() may only be called inside an event handler');\n }\n\n throw createCommandKitError(CommandKitErrorCodes.StopEvents);\n}\n"],"mappings":";;;;;;;;;;AAaA,SAAgB,iBAAwB;AACtC,OAAM,0CAAsB,yCAAqB,eAAe;AAClE;;;;;;;;;;;;;AAcA,SAAgB,QAAQ,OAAsB;AAC5C,KAAI,sCAAkB,MAAM,CAAE,OAAM;AACtC;;;;AAKA,SAAgB,WAAkB;AAChC,OAAM,0CAAsB,yCAAqB,iBAAiB;AACpE;;;;;;;;;;;;;AAcA,SAAgB,aAAoB;AAClC,MAAK,8CAAmB,UAAU,CAChC,OAAM,IAAI,MAAM;AAGlB,OAAM,0CAAsB,yCAAqB,WAAW;AAC9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"type-checker-BATr8TiL.js","names":[],"sources":["../src/cli/type-checker.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { loadTypeScript } from './common';\nimport { join, relative } from 'node:path';\nimport colors from '../utils/colors';\n\nconst TS_NOT_FOUND_ERR = `TypeScript must be installed in order to use the type checker. Please install it using \\`npm install typescript\\` or \\`yarn add typescript\\``;\n\n/**\n * Formats a TypeScript diagnostic message in a pretty, readable format\n * @private\n * @internal\n */\nfunction formatDiagnostic(\n ts: typeof import('typescript'),\n diagnostic: import('typescript').Diagnostic,\n cwd: string,\n): string {\n const messageText = ts.flattenDiagnosticMessageText(\n diagnostic.messageText,\n '\\n',\n );\n\n if (!diagnostic.file) {\n return `${colors.red('error')}: ${messageText}`;\n }\n\n const { line, character } = ts.getLineAndCharacterOfPosition(\n diagnostic.file,\n diagnostic.start!,\n );\n const fileName = relative(cwd, diagnostic.file.fileName);\n const position = `${line + 1}:${character + 1}`;\n const errorCode = diagnostic.code ? `TS${diagnostic.code}` : '';\n\n // Format the error message nicely\n return [\n `${colors.bold(colors.cyan(fileName))}:${colors.bold(colors.yellow(position))} - ${colors.red('error')} ${colors.gray(errorCode)}`,\n `${messageText}`,\n ].join('\\n');\n}\n\n/**\n * Performs a type check on the project using TypeScript.\n * @param path The project root or cwd\n * @private\n * @internal\n */\nexport async function performTypeCheck(path: string) {\n const tsconfigPath = join(path, 'tsconfig.json');\n\n if (!existsSync(tsconfigPath)) return;\n\n const ts = await loadTypeScript(TS_NOT_FOUND_ERR);\n\n // Format host for error reporting\n const formatHost = {\n getCanonicalFileName: (path: string) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n };\n\n // Read tsconfig.json\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configFile.error) {\n console.error(\n colors.red(\n `Error reading tsconfig.json: ${ts.formatDiagnostic(configFile.error, formatHost)}`,\n ),\n );\n process.exit(1);\n }\n\n // Parse the config file\n const parsedConfig = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n path,\n );\n\n // Force noEmit to true as we only want type checking\n parsedConfig.options.noEmit = true;\n\n // Create a program\n const program = ts.createProgram({\n rootNames: parsedConfig.fileNames,\n options: parsedConfig.options,\n projectReferences: parsedConfig.projectReferences,\n });\n\n // Get the diagnostics\n const diagnostics = [\n ...program.getOptionsDiagnostics(),\n ...program.getGlobalDiagnostics(),\n ...program.getSyntacticDiagnostics(),\n ...program.getSemanticDiagnostics(),\n ];\n\n // Report any errors\n if (diagnostics.length > 0) {\n console.log('');\n console.error(\n colors.bold(\n colors.red('Type checking failed with the following errors:'),\n ),\n );\n console.log('');\n\n // Group diagnostics by file for better readability\n const byFile = new Map<string, import('typescript').Diagnostic[]>();\n\n for (const diagnostic of diagnostics) {\n const fileName = diagnostic.file ? diagnostic.file.fileName : 'Global';\n if (!byFile.has(fileName)) {\n byFile.set(fileName, []);\n }\n byFile.get(fileName)!.push(diagnostic);\n }\n\n // Pretty-print each diagnostic\n const totalErrors = diagnostics.length;\n let counter = 0;\n\n for (const [_, fileDiags] of byFile) {\n for (const diagnostic of fileDiags) {\n counter++;\n console.log(formatDiagnostic(ts, diagnostic, path));\n // Add separator between errors for better readability, except for the last one\n if (counter < totalErrors) {\n console.log('');\n }\n }\n }\n\n console.log('');\n console.error(\n colors.bold(\n colors.red(`Found ${totalErrors} error${totalErrors > 1 ? 's' : ''}`),\n ),\n );\n console.log('');\n\n process.exit(1);\n }\n\n console.log(colors.green('✓ Type checking completed successfully.'));\n}\n"],"mappings":";;;;;;;AAKA,MAAM,oBAAoB;;;;;;AAO1B,SAAS,iBACT,IACA,YACA,KACS;CACP,MAAM,cAAc,GAAG,6BACrB,WAAW,aACX,KACD;AAED,MAAK,WAAW,KACd,SAAQ,EAAE,8BAAO,IAAI,QAAQ,CAAC,IAAI,YAAY;CAGhD,MAAM,EAAE,MAAM,WAAW,GAAG,GAAG,8BAC7B,WAAW,MACX,WAAW,MACZ;CACD,MAAM,WAAW,wBAAS,KAAK,WAAW,KAAK,SAAS;CACxD,MAAM,YAAY,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE;CAC9C,MAAM,YAAY,WAAW,QAAQ,IAAI,WAAW,KAAK,IAAI;AAG7D,QAAO,EACN,EAAE,8BAAO,KAAK,8BAAO,KAAK,SAAS,CAAC,CAAC,GAAG,8BAAO,KAAK,8BAAO,OAAO,SAAS,CAAC,CAAC,KAAK,8BAAO,IAAI,QAAQ,CAAC,GAAG,8BAAO,KAAK,UAAU,CAAC,IAChI,EAAE,YAAY,CAAE,EACjB,KAAK,KAAK;AACZ;;;;;;;AAQA,eAAsB,iBAAiB,MAAc;CACnD,MAAM,eAAe,oBAAK,MAAM,gBAAgB;AAEhD,MAAK,wBAAW,aAAa,CAAE;CAE/B,MAAM,KAAK,MAAM,8BAAe,iBAAiB;CAGjD,MAAM,aAAa;EACjB,sBAAsB,CAAC,WAAiB;EACxC,qBAAqB,GAAG,IAAI;EAC5B,YAAY,MAAM,GAAG,IAAI;CAC1B;CAGD,MAAM,aAAa,GAAG,eAAe,cAAc,GAAG,IAAI,SAAS;AAEnE,KAAI,WAAW,OAAO;AACpB,UAAQ,MACN,8BAAO,KACJ,+BAA+B,GAAG,iBAAiB,WAAW,OAAO,WAAW,CAAC,EACnF,CACF;AACD,UAAQ,KAAK,EAAE;CACjB;CAGA,MAAM,eAAe,GAAG,2BACtB,WAAW,QACX,GAAG,KACH,KACD;AAGD,cAAa,QAAQ,SAAS;CAG9B,MAAM,UAAU,GAAG,cAAc;EAC/B,WAAW,aAAa;EACxB,SAAS,aAAa;EACtB,mBAAmB,aAAa;CACjC,EAAC;CAGF,MAAM,cAAc;EACpB,GAAG,QAAQ,uBAAuB;EAClC,GAAG,QAAQ,sBAAsB;EACjC,GAAG,QAAQ,yBAAyB;EACpC,GAAG,QAAQ,wBAAwB;CAAC;AAIpC,KAAI,YAAY,SAAS,GAAG;AAC1B,UAAQ,IAAI,GAAG;AACf,UAAQ,MACN,8BAAO,KACL,8BAAO,IAAI,kDAAkD,CAC9D,CACF;AACD,UAAQ,IAAI,GAAG;EAGf,MAAM,yBAAS,IAAI;AAEnB,OAAK,MAAM,cAAc,aAAa;GACpC,MAAM,WAAW,WAAW,OAAO,WAAW,KAAK,WAAW;AAC9D,QAAK,OAAO,IAAI,SAAS,CACvB,QAAO,IAAI,UAAU,CAAE,EAAC;AAE1B,UAAO,IAAI,SAAS,CAAE,KAAK,WAAW;EACxC;EAGA,MAAM,cAAc,YAAY;EAChC,IAAI,UAAU;AAEd,OAAK,MAAM,CAAC,GAAG,UAAU,IAAI,OAC3B,MAAK,MAAM,cAAc,WAAW;AAClC;AACA,WAAQ,IAAI,iBAAiB,IAAI,YAAY,KAAK,CAAC;AAEnD,OAAI,UAAU,YACZ,SAAQ,IAAI,GAAG;EAEnB;AAGF,UAAQ,IAAI,GAAG;AACf,UAAQ,MACN,8BAAO,KACL,8BAAO,KAAK,QAAQ,YAAY,QAAQ,cAAc,IAAI,MAAM,GAAG,EAAE,CACtE,CACF;AACD,UAAQ,IAAI,GAAG;AAEf,UAAQ,KAAK,EAAE;CACjB;AAEA,SAAQ,IAAI,8BAAO,MAAM,0CAA0C,CAAC;AACtE"}
1
+ {"version":3,"file":"type-checker-BATr8TiL.js","names":[],"sources":["../src/cli/type-checker.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { loadTypeScript } from './common';\nimport { join, relative } from 'node:path';\nimport colors from '../utils/colors';\n\nconst TS_NOT_FOUND_ERR = `TypeScript must be installed in order to use the type checker. Please install it using \\`npm install typescript\\` or \\`yarn add typescript\\``;\n\n/**\n * Formats a TypeScript diagnostic message in a pretty, readable format\n * @private\n * @internal\n */\nfunction formatDiagnostic(\n ts: typeof import('typescript'),\n diagnostic: import('typescript').Diagnostic,\n cwd: string,\n): string {\n const messageText = ts.flattenDiagnosticMessageText(\n diagnostic.messageText,\n '\\n',\n );\n\n if (!diagnostic.file) {\n return `${colors.red('error')}: ${messageText}`;\n }\n\n const { line, character } = ts.getLineAndCharacterOfPosition(\n diagnostic.file,\n diagnostic.start!,\n );\n const fileName = relative(cwd, diagnostic.file.fileName);\n const position = `${line + 1}:${character + 1}`;\n const errorCode = diagnostic.code ? `TS${diagnostic.code}` : '';\n\n // Format the error message nicely\n return [\n `${colors.bold(colors.cyan(fileName))}:${colors.bold(colors.yellow(position))} - ${colors.red('error')} ${colors.gray(errorCode)}`,\n `${messageText}`,\n ].join('\\n');\n}\n\n/**\n * Performs a type check on the project using TypeScript.\n * @param path The project root or cwd\n * @private\n * @internal\n */\nexport async function performTypeCheck(path: string) {\n const tsconfigPath = join(path, 'tsconfig.json');\n\n if (!existsSync(tsconfigPath)) return;\n\n const ts = await loadTypeScript(TS_NOT_FOUND_ERR);\n\n // Format host for error reporting\n const formatHost = {\n getCanonicalFileName: (path: string) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n };\n\n // Read tsconfig.json\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configFile.error) {\n console.error(\n colors.red(\n `Error reading tsconfig.json: ${ts.formatDiagnostic(configFile.error, formatHost)}`,\n ),\n );\n process.exit(1);\n }\n\n // Parse the config file\n const parsedConfig = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n path,\n );\n\n // Force noEmit to true as we only want type checking\n parsedConfig.options.noEmit = true;\n\n // Create a program\n const program = ts.createProgram({\n rootNames: parsedConfig.fileNames,\n options: parsedConfig.options,\n projectReferences: parsedConfig.projectReferences,\n });\n\n // Get the diagnostics\n const diagnostics = [\n ...program.getOptionsDiagnostics(),\n ...program.getGlobalDiagnostics(),\n ...program.getSyntacticDiagnostics(),\n ...program.getSemanticDiagnostics(),\n ];\n\n // Report any errors\n if (diagnostics.length > 0) {\n console.log('');\n console.error(\n colors.bold(\n colors.red('Type checking failed with the following errors:'),\n ),\n );\n console.log('');\n\n // Group diagnostics by file for better readability\n const byFile = new Map<string, import('typescript').Diagnostic[]>();\n\n for (const diagnostic of diagnostics) {\n const fileName = diagnostic.file ? diagnostic.file.fileName : 'Global';\n if (!byFile.has(fileName)) {\n byFile.set(fileName, []);\n }\n byFile.get(fileName)!.push(diagnostic);\n }\n\n // Pretty-print each diagnostic\n const totalErrors = diagnostics.length;\n let counter = 0;\n\n for (const [_, fileDiags] of byFile) {\n for (const diagnostic of fileDiags) {\n counter++;\n console.log(formatDiagnostic(ts, diagnostic, path));\n // Add separator between errors for better readability, except for the last one\n if (counter < totalErrors) {\n console.log('');\n }\n }\n }\n\n console.log('');\n console.error(\n colors.bold(\n colors.red(`Found ${totalErrors} error${totalErrors > 1 ? 's' : ''}`),\n ),\n );\n console.log('');\n\n process.exit(1);\n }\n\n console.log(colors.green('✓ Type checking completed successfully.'));\n}\n"],"mappings":";;;;;;;AAKA,MAAM,oBAAoB;;;;;;AAO1B,SAAS,iBACT,IACA,YACA,KACS;CACP,MAAM,cAAc,GAAG,6BACrB,WAAW,aACX,KACD;AAED,MAAK,WAAW,KACd,WAAU,8BAAO,IAAI,QAAQ,CAAC,IAAI;CAGpC,MAAM,EAAE,MAAM,WAAW,GAAG,GAAG,8BAC7B,WAAW,MACX,WAAW,MACZ;CACD,MAAM,WAAW,wBAAS,KAAK,WAAW,KAAK,SAAS;CACxD,MAAM,cAAc,OAAO,EAAE,GAAG,YAAY;CAC5C,MAAM,YAAY,WAAW,QAAQ,IAAI,WAAW,SAAS;AAG7D,QAAO,IACJ,8BAAO,KAAK,8BAAO,KAAK,SAAS,CAAC,CAAC,GAAG,8BAAO,KAAK,8BAAO,OAAO,SAAS,CAAC,CAAC,KAAK,8BAAO,IAAI,QAAQ,CAAC,GAAG,8BAAO,KAAK,UAAU,OAC7H,aAAc,EACjB,KAAK,KAAK;AACZ;;;;;;;AAQA,eAAsB,iBAAiB,MAAc;CACnD,MAAM,eAAe,oBAAK,MAAM,gBAAgB;AAEhD,MAAK,wBAAW,aAAa,CAAE;CAE/B,MAAM,KAAK,MAAM,8BAAe,iBAAiB;CAGjD,MAAM,aAAa;EACjB,sBAAsB,CAAC,WAAiB;EACxC,qBAAqB,GAAG,IAAI;EAC5B,YAAY,MAAM,GAAG,IAAI;CAC1B;CAGD,MAAM,aAAa,GAAG,eAAe,cAAc,GAAG,IAAI,SAAS;AAEnE,KAAI,WAAW,OAAO;AACpB,UAAQ,MACN,8BAAO,KACJ,+BAA+B,GAAG,iBAAiB,WAAW,OAAO,WAAW,GAClF,CACF;AACD,UAAQ,KAAK,EAAE;CACjB;CAGA,MAAM,eAAe,GAAG,2BACtB,WAAW,QACX,GAAG,KACH,KACD;AAGD,cAAa,QAAQ,SAAS;CAG9B,MAAM,UAAU,GAAG,cAAc;EAC/B,WAAW,aAAa;EACxB,SAAS,aAAa;EACtB,mBAAmB,aAAa;CACjC,EAAC;CAGF,MAAM,cAAc;EACpB,GAAG,QAAQ,uBAAuB;EAClC,GAAG,QAAQ,sBAAsB;EACjC,GAAG,QAAQ,yBAAyB;EACpC,GAAG,QAAQ,wBAAwB;CAAC;AAIpC,KAAI,YAAY,SAAS,GAAG;AAC1B,UAAQ,IAAI,GAAG;AACf,UAAQ,MACN,8BAAO,KACL,8BAAO,IAAI,kDAAkD,CAC9D,CACF;AACD,UAAQ,IAAI,GAAG;EAGf,MAAM,yBAAS,IAAI;AAEnB,OAAK,MAAM,cAAc,aAAa;GACpC,MAAM,WAAW,WAAW,OAAO,WAAW,KAAK,WAAW;AAC9D,QAAK,OAAO,IAAI,SAAS,CACvB,QAAO,IAAI,UAAU,CAAE,EAAC;AAE1B,UAAO,IAAI,SAAS,CAAE,KAAK,WAAW;EACxC;EAGA,MAAM,cAAc,YAAY;EAChC,IAAI,UAAU;AAEd,OAAK,MAAM,CAAC,GAAG,UAAU,IAAI,OAC3B,MAAK,MAAM,cAAc,WAAW;AAClC;AACA,WAAQ,IAAI,iBAAiB,IAAI,YAAY,KAAK,CAAC;AAEnD,OAAI,UAAU,YACZ,SAAQ,IAAI,GAAG;EAEnB;AAGF,UAAQ,IAAI,GAAG;AACf,UAAQ,MACN,8BAAO,KACL,8BAAO,KAAK,QAAQ,YAAY,QAAQ,cAAc,IAAI,MAAM,KAAK,CACtE,CACF;AACD,UAAQ,IAAI,GAAG;AAEf,UAAQ,KAAK,EAAE;CACjB;AAEA,SAAQ,IAAI,8BAAO,MAAM,0CAA0C,CAAC;AACtE"}
@@ -1,7 +1,7 @@
1
- import * as picocolors_types8 from "picocolors/types";
1
+ import * as picocolors_types6 from "picocolors/types";
2
2
 
3
3
  //#region src/utils/colors.d.ts
4
- declare const _default: picocolors_types8.Colors;
4
+ declare const _default: picocolors_types6.Colors;
5
5
  //#endregion
6
6
  export { _default as default };
7
7
  //# sourceMappingURL=colors.d.ts.map
@@ -1,7 +1,7 @@
1
1
  require('../colors-Cd4Oz-r-.js');
2
2
  require('../ActionRow-CmTHbo2t.js');
3
- require('../error-codes-DXOuid4c.js');
4
- const require_CommandKit = require('../CommandKit-DkPVD3wV.js');
3
+ require('../error-codes-C-ViHyu-.js');
4
+ const require_CommandKit = require('../CommandKit-DuH9iT2t.js');
5
5
  require('../common-CcfjYnPG.js');
6
6
  require('../common-vnMIelAE.js');
7
7
  require('../container-DCjIgp-B.js');
@@ -23,9 +23,9 @@ require('../runtime-5fxB4uhe.js');
23
23
  require('../resolve-file-url-9aPt6A_n.js');
24
24
  require('../types-package-MDczrp9f.js');
25
25
  require('../EventWorkerContext-DxfS_0fJ.js');
26
- require('../signals-lSAO5hOr.js');
26
+ require('../signals-Bu7gndaS.js');
27
27
  require('../constants-R96vEAFD.js');
28
- require('../MessageCommandParser-CUZrGknY.js');
28
+ require('../MessageCommandParser-CGhN3xNN.js');
29
29
  require('../CommandsRouter-Bs9UuowL.js');
30
30
  require('../EventsRouter-B7oifgM6.js');
31
31
  require('../router-wA3kFzES.js');
@@ -1,4 +1,4 @@
1
- const require_error_codes = require('../error-codes-DXOuid4c.js');
1
+ const require_error_codes = require('../error-codes-C-ViHyu-.js');
2
2
 
3
3
  exports.CommandKitErrorCodes = require_error_codes.CommandKitErrorCodes;
4
4
  exports.createCommandKitError = require_error_codes.createCommandKitError;