From fc51f0d595c9d6a438ad876b57a8165a517ec39c Mon Sep 17 00:00:00 2001 From: RedStar Date: Tue, 20 Oct 2026 17:08:58 +0200 Subject: [PATCH 1/2] feat: set meta.configKey in every module Each module owns a top-level key of stars.config (api, broker, cache, gateway, i18n, logger, scheduledTasks, sharder, subcommandsAdvanced), typed through a StarsConfig augmentation, so options no longer have to go through the [specifier, options] tuple, which still works and wins over the key. Requires @wolfstar/kit ^0.2.0, the first version that reads configKey, and adds @wolfstar/schema as an optional peer for the augmentation. Refs #258 --- .changeset/modules-config-key.md | 15 ++ AGENTS.md | 3 +- package.json | 2 + packages/plugin-api/README.md | 12 +- packages/plugin-api/package.json | 9 +- packages/plugin-api/src/module.ts | 14 +- packages/plugin-broker/README.md | 13 +- packages/plugin-broker/package.json | 9 +- packages/plugin-broker/src/module.ts | 15 +- packages/plugin-cache/README.md | 3 +- packages/plugin-cache/package.json | 9 +- packages/plugin-cache/src/module.ts | 18 +- packages/plugin-gateway/README.md | 2 +- packages/plugin-gateway/package.json | 9 +- packages/plugin-gateway/src/module.ts | 22 +- packages/plugin-i18next/README.md | 13 +- packages/plugin-i18next/package.json | 9 +- packages/plugin-i18next/src/module.ts | 15 +- packages/plugin-logger/README.md | 38 +-- packages/plugin-logger/package.json | 9 +- packages/plugin-logger/src/module.ts | 22 +- packages/plugin-scheduled-tasks/README.md | 16 +- packages/plugin-scheduled-tasks/package.json | 11 +- packages/plugin-scheduled-tasks/src/module.ts | 15 +- .../tests/module.test.ts | 1 + packages/plugin-sharder/README.md | 2 +- packages/plugin-sharder/package.json | 9 +- packages/plugin-sharder/src/module.ts | 18 +- .../plugin-subcommands-advanced/README.md | 3 +- .../plugin-subcommands-advanced/package.json | 9 +- .../plugin-subcommands-advanced/src/module.ts | 17 +- pnpm-lock.yaml | 235 +++++------------- tests/module-config-keys.test.ts | 132 ++++++++++ tests/module-entries.test.ts | 10 +- 34 files changed, 480 insertions(+), 259 deletions(-) create mode 100644 .changeset/modules-config-key.md create mode 100644 tests/module-config-keys.test.ts diff --git a/.changeset/modules-config-key.md b/.changeset/modules-config-key.md new file mode 100644 index 00000000..e6392f74 --- /dev/null +++ b/.changeset/modules-config-key.md @@ -0,0 +1,15 @@ +--- +"@wolfstar/plugin-api": minor +"@wolfstar/plugin-broker": minor +"@wolfstar/plugin-cache": minor +"@wolfstar/plugin-gateway": minor +"@wolfstar/plugin-i18next": minor +"@wolfstar/plugin-logger": minor +"@wolfstar/plugin-scheduled-tasks": minor +"@wolfstar/plugin-sharder": minor +"@wolfstar/plugin-subcommands-advanced": minor +--- + +Every module sets `meta.configKey`, so an application writes a module's options under its own top-level key of `stars.config` (`api`, `broker`, `cache`, `gateway`, `i18n`, `logger`, `scheduledTasks`, `sharder`, `subcommandsAdvanced`) instead of the `[specifier, options]` tuple of `modules`. The tuple still works and is merged over the key. The key is typed in `defineConfig` once the module is imported in `stars.config.ts`; `cache`, `gateway`, `sharder` and `subcommandsAdvanced` take no options yet and only reserve their name. + +The `@wolfstar/kit` peer range moves from `^0.1.0` to `^0.2.0`, the first version that reads `configKey`, and `@wolfstar/schema` (`^0.9.0`) is a new optional peer that carries the `StarsConfig` type the keys extend. A project on `@wolfstar/kit` 0.1 has to update it. diff --git a/AGENTS.md b/AGENTS.md index a7a6ee6f..cd11517d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -79,7 +79,8 @@ pnpm changeset # add a changeset (`pnpm changeset --e - CI runs on GitHub-hosted runners (`ubuntu-24.04-arm` for `ci.yml` and `pkg-pr-new.yml`, `ubuntu-latest` for `release.yml`) — not Blacksmith, despite some now-superseded PR history. - Adding a new package: add a matching `packages:` entry to **both** `.github/labels.yml` (label sync) and `.github/labeler.yml` (path-based auto-labeling on PRs) — these can drift independently (e.g. `plugin-subcommands-advanced` currently has no `labeler.yml` path mapping, and its `labels.yml` entry is misspelled `packages:plugins-subcommands-advanced`, so it's never auto-applied) — add its name to the `scopes` list of `semantic-pull-requests.yml`, and append its `tsconfig.consumption.json` (if any) to the root `typecheck` script. - `tests/http-framework-peer-range.test.ts` (part of `pnpm test`, so the CI `unit` job) fails when any non-private package's `peerDependencies["@wolfstar/http-framework"]` excludes the framework version the workspace installs (its devDependency, kept on the latest release by Renovate), when a package declaring that peer doesn't also devDepend on it, or when the packages' peer ranges accept different majors (a package whose range starts at a later major, like `plugin-scheduled-tasks`' `^6.1.0`, only has to match from that major up). When Renovate bumps the framework to a new major, widen **every** plugin's peer range (`^x || ^.0.0`) in the same PR **and** add a patch changeset per package — a peer-range change on `main` isn't published without one (that is how `plugin-api`/`plugin-logger`/`plugin-subcommands-advanced` shipped `^3`-only peers to npm after the v5 bump, #121). -- Activation has two paths. `plugin-scheduled-tasks` is module-only (its `./register` is a no-op). The older plugins ship `./module` (default export: `defineModule` from `@wolfstar/kit`, optional peer) and, for those with runtime hooks, `./plugin` (default export: a `definePlugin` factory); `./register` stays the legacy class + `Client.plugins.register*Hook` path for framework v3/v5/v6. Both call the same functions in `src/hooks.ts`, so change behaviour there. The `stars` CLI never imports `/register` itself; it only preloads the sources registered through `ctx.addPlugin`, so a user's own `import "/register"` (or passing the `./plugin` factory to `plugins` while also importing `/register`) still double-installs the hooks. `tests/module-entries.test.ts` checks that every `src/module.ts` (except `plugin-scheduled-tasks`, excluded on purpose) is exported, built and has kit as an optional peer. +- Activation has two paths. `plugin-scheduled-tasks` is module-only (its `./register` is a no-op). The older plugins ship `./module` (default export: `defineModule` from `@wolfstar/kit`, optional peer) and, for those with runtime hooks, `./plugin` (default export: a `definePlugin` factory); `./register` stays the legacy class + `Client.plugins.register*Hook` path for framework v3/v5/v6. Both call the same functions in `src/hooks.ts`, so change behaviour there. The `stars` CLI never imports `/register` itself; it only preloads the sources registered through `ctx.addPlugin`, so a user's own `import "/register"` (or passing the `./plugin` factory to `plugins` while also importing `/register`) still double-installs the hooks. `tests/module-entries.test.ts` checks that every `src/module.ts` (except `plugin-scheduled-tasks`, excluded on purpose) is exported, built and has kit and schema as optional peers. +- Module config keys: every `defineModule` sets `meta.configKey`, so a project writes the options under that top-level key of `stars.config` instead of the `[specifier, options]` tuple (the tuple is merged over the key and wins). Needs `@wolfstar/kit` `^0.2.0` (the peer and dev range of every package with a `src/module.ts`), and each `module.ts` augments `StarsConfig` from `@wolfstar/schema` (an optional peer and devDependency) to type the key. Keys: `plugin-api` `api`, `plugin-broker` `broker`, `plugin-cache` `cache`, `plugin-gateway` `gateway`, `plugin-i18next` `i18n`, `plugin-logger` `logger`, `plugin-scheduled-tasks` `scheduledTasks`, `plugin-sharder` `sharder`, `plugin-subcommands-advanced` `subcommandsAdvanced`; `cache`, `gateway`, `sharder` and `subcommandsAdvanced` take no options yet and only reserve the name. A key must be unique and not a built-in key (`BUILT_IN_CONFIG_KEYS` of `@wolfstar/schema`); renaming one is a breaking change. `tests/module-config-keys.test.ts` runs every module through kit's `setupModules`. What sits under a key is written into the build, so it must be JSON. ## Notes for agents diff --git a/package.json b/package.json index 22855874..bc2b0b8d 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,8 @@ "@types/semver": "^7.8.0", "@types/ws": "^8.18.2", "@vitest/coverage-v8": "^5.0.3", + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0", "cz-conventional-changelog": "^3.3.0", "golar": "^0.1.10", "husky": "9.1.7", diff --git a/packages/plugin-api/README.md b/packages/plugin-api/README.md index 9bbe5dec..8b996973 100644 --- a/packages/plugin-api/README.md +++ b/packages/plugin-api/README.md @@ -33,16 +33,22 @@ Requires Node.js `>=20.18.1`. ### Stars module -On framework 6.1 and later, list the module in `modules` in `stars.config` (needs the optional -`@wolfstar/kit` peer): +On framework 6.1 and later, list the module in `modules` in `stars.config` and write its options +under the `api` key (needs the optional `@wolfstar/kit` peer, 0.2 or later): ```ts // stars.config.ts +import type {} from "@wolfstar/plugin-api/module"; // types the `api` key in `defineConfig` + export default defineConfig({ - modules: [["@wolfstar/plugin-api/module", { prefix: "v1", listenOptions: { port: 4000 } }]], + modules: ["@wolfstar/plugin-api/module"], + api: { prefix: "v1", listenOptions: { port: 4000 } }, }); ``` +The `[specifier, options]` tuple still works: `modules: [["@wolfstar/plugin-api/module", { prefix: "v1" }]]`. +Its options are merged over the `api` key, so they win. + The options are written into the built entry, so they must be JSON-serialisable. Anything that is not (for example `server` options holding functions or buffers) goes through `ClientOptions.api`, which is merged over the module options. diff --git a/packages/plugin-api/package.json b/packages/plugin-api/package.json index 8d50731b..2d8ae278 100644 --- a/packages/plugin-api/package.json +++ b/packages/plugin-api/package.json @@ -73,15 +73,20 @@ "devDependencies": { "@redstardev/unplugin-version-injector": "^0.0.2", "@wolfstar/http-framework": "^6.1.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependencies": { "@wolfstar/http-framework": "^3.6.0 || ^5.0.0 || ^6.0.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependenciesMeta": { "@wolfstar/kit": { "optional": true + }, + "@wolfstar/schema": { + "optional": true } }, "engines": { diff --git a/packages/plugin-api/src/module.ts b/packages/plugin-api/src/module.ts index ae0baa59..7da55fbb 100644 --- a/packages/plugin-api/src/module.ts +++ b/packages/plugin-api/src/module.ts @@ -3,9 +3,11 @@ import type { ServerOptions } from "./lib/structures/http/Server"; /** * The Stars module: listing `@wolfstar/plugin-api/module` in `modules` in `stars.config` registers the API plugin with - * the options written there. + * the options written under its `api` key. * * @remarks + * The `[specifier, options]` tuple of `modules` still works: its options are merged over the `api` key, so they win. + * * The options are written into the built entry, so they have to be JSON-serialisable. Pass anything that is not * (such as the `server` options holding functions or buffers) through `ClientOptions.api`, which is merged over the * module options. @@ -14,16 +16,24 @@ import type { ServerOptions } from "./lib/structures/http/Server"; * ```ts * // stars.config.ts * export default defineConfig({ - * modules: [['@wolfstar/plugin-api/module', { prefix: '/api' }]], + * modules: ['@wolfstar/plugin-api/module'], + * api: { prefix: '/api' }, * }); * ``` */ export default defineModule({ meta: { name: "@wolfstar/plugin-api", + configKey: "api", compatibility: { framework: ">=6.1.0" }, }, setup(options, ctx) { ctx.addPlugin({ from: "@wolfstar/plugin-api/plugin", options }); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + api?: ServerOptions; + } +} diff --git a/packages/plugin-broker/README.md b/packages/plugin-broker/README.md index 17082732..ccfbda32 100644 --- a/packages/plugin-broker/README.md +++ b/packages/plugin-broker/README.md @@ -51,16 +51,23 @@ await broker.publish("messageCreate", payload); #### Stars module -On framework 6.1 and later, list the module in `modules` in `stars.config` (needs the optional -`@wolfstar/kit` peer): +On framework 6.1 and later, list the module in `modules` in `stars.config` and write its options +under the `broker` key (needs the optional `@wolfstar/kit` peer, 0.2 or later): ```ts // stars.config.ts +import type {} from "@wolfstar/plugin-broker/module"; // types the `broker` key in `defineConfig` + export default defineConfig({ - modules: [["@wolfstar/plugin-broker/module", { stream: "wolfstar:events", group: "workers" }]], + modules: ["@wolfstar/plugin-broker/module"], + broker: { stream: "wolfstar:events", group: "workers" }, }); ``` +The `[specifier, options]` tuple still works: +`modules: [["@wolfstar/plugin-broker/module", { stream: "wolfstar:events" }]]`. Its options are merged +over the `broker` key, so they win. + The options are written into the built entry, so they must be JSON-serialisable. `redis` is a client instance and `consumer` is per-process (for example `worker-${process.pid}`), so neither can live in `stars.config`: supply both through `ClientOptions.broker`, which is shallow-merged over the module diff --git a/packages/plugin-broker/package.json b/packages/plugin-broker/package.json index cec3e012..aedac359 100644 --- a/packages/plugin-broker/package.json +++ b/packages/plugin-broker/package.json @@ -74,17 +74,22 @@ "devDependencies": { "@sapphire/pieces": "^4.4.1", "@wolfstar/http-framework": "^6.1.0", - "@wolfstar/kit": "^0.1.0", + "@wolfstar/kit": "^0.2.0", "@wolfstar/plugin-gateway": "workspace:^", + "@wolfstar/schema": "^0.9.0", "ioredis": "^6.0.0" }, "peerDependencies": { "@wolfstar/http-framework": "^3.4.0 || ^5.0.0 || ^6.0.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependenciesMeta": { "@wolfstar/kit": { "optional": true + }, + "@wolfstar/schema": { + "optional": true } }, "engines": { diff --git a/packages/plugin-broker/src/module.ts b/packages/plugin-broker/src/module.ts index 9620051c..5eb54d31 100644 --- a/packages/plugin-broker/src/module.ts +++ b/packages/plugin-broker/src/module.ts @@ -3,9 +3,12 @@ import type { BrokerConsumerOptions } from "./BrokerConsumer.js"; /** * The Stars module: listing `@wolfstar/plugin-broker/module` in `modules` in `stars.config` registers the broker - * plugin with the options written there. + * plugin with the options written under its `broker` key. * * @remarks + * The `[specifier, options]` tuple of `modules` still works: its options are merged over the `broker` key, so they + * win. + * * The options are written into the built entry, so they have to be JSON-serialisable. `redis` is a client instance * and `consumer` is per-process, so neither can be written in `stars.config`: supply both through * `ClientOptions.broker`, which is shallow-merged over the module options (the module options are the base values @@ -17,16 +20,24 @@ import type { BrokerConsumerOptions } from "./BrokerConsumer.js"; * ```ts * // stars.config.ts * export default defineConfig({ - * modules: [['@wolfstar/plugin-broker/module', { stream: 'wolfstar:events', group: 'workers' }]], + * modules: ['@wolfstar/plugin-broker/module'], + * broker: { stream: 'wolfstar:events', group: 'workers' }, * }); * ``` */ export default defineModule>({ meta: { name: "@wolfstar/plugin-broker", + configKey: "broker", compatibility: { framework: ">=6.1.0" }, }, setup(options, ctx) { ctx.addPlugin({ from: "@wolfstar/plugin-broker/plugin", options }); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + broker?: Partial; + } +} diff --git a/packages/plugin-cache/README.md b/packages/plugin-cache/README.md index 14d66651..877f9dfb 100644 --- a/packages/plugin-cache/README.md +++ b/packages/plugin-cache/README.md @@ -293,7 +293,8 @@ export default defineConfig({ ``` The module registers no plugin and takes no options: the cache itself is still constructed by -`@wolfstar/plugin-gateway`. +`@wolfstar/plugin-gateway`. It owns the `cache` key of `stars.config` (reserved for future options), so no +other module can claim it. ## Credits diff --git a/packages/plugin-cache/package.json b/packages/plugin-cache/package.json index 98288b28..36647f60 100644 --- a/packages/plugin-cache/package.json +++ b/packages/plugin-cache/package.json @@ -69,18 +69,23 @@ "discord-api-types": "^0.38.33" }, "devDependencies": { - "@wolfstar/kit": "^0.1.0", + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0", "ioredis": "^6.0.0", "msgpackr": "^2.1.0" }, "peerDependencies": { - "@wolfstar/kit": "^0.1.0", + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0", "msgpackr": "^2.0.0" }, "peerDependenciesMeta": { "@wolfstar/kit": { "optional": true }, + "@wolfstar/schema": { + "optional": true + }, "msgpackr": { "optional": true } diff --git a/packages/plugin-cache/src/module.ts b/packages/plugin-cache/src/module.ts index 7c382dd5..7db5f23c 100644 --- a/packages/plugin-cache/src/module.ts +++ b/packages/plugin-cache/src/module.ts @@ -1,12 +1,26 @@ import { defineModule } from "@wolfstar/kit"; +/** + * The options of the module: none yet. The `cache` key of `stars.config` is reserved for them. + */ +export type CacheModuleOptions = Record; + /** * The Stars module: listing `@wolfstar/plugin-cache/module` in `modules` in `stars.config` adds the package to the * auto imports. The cache itself is constructed by `@wolfstar/plugin-gateway`. + * + * @remarks + * The module owns the `cache` key of `stars.config`, which takes no options for now. */ -export default defineModule({ - meta: { name: "@wolfstar/plugin-cache" }, +export default defineModule({ + meta: { name: "@wolfstar/plugin-cache", configKey: "cache" }, setup(_options, ctx) { ctx.addImports("@wolfstar/plugin-cache"); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + cache?: CacheModuleOptions; + } +} diff --git a/packages/plugin-gateway/README.md b/packages/plugin-gateway/README.md index aada338e..9c4b4b48 100644 --- a/packages/plugin-gateway/README.md +++ b/packages/plugin-gateway/README.md @@ -1318,7 +1318,7 @@ export default defineConfig({ }); ``` -The module registers no plugin and takes no options: you still construct the `GatewayClient` yourself. +The module registers no plugin and takes no options: you still construct the `GatewayClient` yourself. It owns the `gateway` key of `stars.config` (reserved for future options), so no other module can claim it. ## Credits diff --git a/packages/plugin-gateway/package.json b/packages/plugin-gateway/package.json index 69a0e463..acd8b5f4 100644 --- a/packages/plugin-gateway/package.json +++ b/packages/plugin-gateway/package.json @@ -70,15 +70,20 @@ }, "devDependencies": { "@wolfstar/http-framework": "^6.1.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependencies": { "@wolfstar/http-framework": "^3.4.0 || ^5.0.0 || ^6.0.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependenciesMeta": { "@wolfstar/kit": { "optional": true + }, + "@wolfstar/schema": { + "optional": true } }, "engines": { diff --git a/packages/plugin-gateway/src/module.ts b/packages/plugin-gateway/src/module.ts index 57d8753c..61bb85cc 100644 --- a/packages/plugin-gateway/src/module.ts +++ b/packages/plugin-gateway/src/module.ts @@ -1,12 +1,30 @@ import { defineModule } from "@wolfstar/kit"; +/** + * The options of the module: none yet. The `gateway` key of `stars.config` is reserved for them. + */ +export type GatewayModuleOptions = Record; + /** * The Stars module: listing `@wolfstar/plugin-gateway/module` in `modules` in `stars.config` adds the package to the * auto imports. The `GatewayClient` is still constructed by you. + * + * @remarks + * The module owns the `gateway` key of `stars.config`, which takes no options for now. */ -export default defineModule({ - meta: { name: "@wolfstar/plugin-gateway", compatibility: { framework: ">=6.1.0" } }, +export default defineModule({ + meta: { + name: "@wolfstar/plugin-gateway", + configKey: "gateway", + compatibility: { framework: ">=6.1.0" }, + }, setup(_options, ctx) { ctx.addImports("@wolfstar/plugin-gateway"); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + gateway?: GatewayModuleOptions; + } +} diff --git a/packages/plugin-i18next/README.md b/packages/plugin-i18next/README.md index 4d4f9df0..8218d02a 100644 --- a/packages/plugin-i18next/README.md +++ b/packages/plugin-i18next/README.md @@ -31,16 +31,23 @@ pnpm add @wolfstar/http-framework @wolfstar/plugin-i18next ### Stars module -On framework 6.1 and later, list the module in `modules` in `stars.config` (needs the optional -`@wolfstar/kit` peer): +On framework 6.1 and later, list the module in `modules` in `stars.config` and write its options +under the `i18n` key (needs the optional `@wolfstar/kit` peer, 0.2 or later): ```ts // stars.config.ts +import type {} from "@wolfstar/plugin-i18next/module"; // types the `i18n` key in `defineConfig` + export default defineConfig({ - modules: [["@wolfstar/plugin-i18next/module", { defaultLanguageDirectory: "./languages" }]], + modules: ["@wolfstar/plugin-i18next/module"], + i18n: { defaultLanguageDirectory: "./languages" }, }); ``` +The `[specifier, options]` tuple still works: +`modules: [["@wolfstar/plugin-i18next/module", { defaultLanguageDirectory: "./languages" }]]`. Its +options are merged over the `i18n` key, so they win. + The options are written into the built entry, so they must be JSON-serialisable. `fetchLanguage` and the functions in `hmr.options` are not: set `fetchLanguage` through `ClientOptions.i18n`, which is merged (shallowly) over the module options. Because the merge is shallow, `hmr: { options }` set diff --git a/packages/plugin-i18next/package.json b/packages/plugin-i18next/package.json index a96873a8..18697deb 100644 --- a/packages/plugin-i18next/package.json +++ b/packages/plugin-i18next/package.json @@ -79,12 +79,14 @@ "devDependencies": { "@wolfstar/http-framework": "^6.1.0", "@wolfstar/i18next-type-generator": "3.1.5", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependencies": { "@wolfstar/http-framework": "^3.1.0 || ^5.0.0 || ^6.0.0", "@wolfstar/i18next-type-generator": "^3.0.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependenciesMeta": { "@wolfstar/i18next-type-generator": { @@ -92,6 +94,9 @@ }, "@wolfstar/kit": { "optional": true + }, + "@wolfstar/schema": { + "optional": true } }, "engines": { diff --git a/packages/plugin-i18next/src/module.ts b/packages/plugin-i18next/src/module.ts index ec1b9459..a679c90b 100644 --- a/packages/plugin-i18next/src/module.ts +++ b/packages/plugin-i18next/src/module.ts @@ -3,9 +3,12 @@ import type { InternationalizationOptions } from "./lib/types"; /** * The Stars module: listing `@wolfstar/plugin-i18next/module` in `modules` in `stars.config` registers the i18next - * plugin with the options written there. + * plugin with the options written under its `i18n` key. * * @remarks + * The `[specifier, options]` tuple of `modules` still works: its options are merged over the `i18n` key, so they + * win. + * * The options are written into the built entry, so they have to be JSON-serialisable. `fetchLanguage` and the * `hmr.options` functions are not: set `fetchLanguage` through `ClientOptions.i18n`. * @@ -13,16 +16,24 @@ import type { InternationalizationOptions } from "./lib/types"; * ```ts * // stars.config.ts * export default defineConfig({ - * modules: [['@wolfstar/plugin-i18next/module', { defaultLanguageDirectory: './languages' }]], + * modules: ['@wolfstar/plugin-i18next/module'], + * i18n: { defaultLanguageDirectory: './languages' }, * }); * ``` */ export default defineModule({ meta: { name: "@wolfstar/plugin-i18next", + configKey: "i18n", compatibility: { framework: ">=6.1.0" }, }, setup(options, ctx) { ctx.addPlugin({ from: "@wolfstar/plugin-i18next/plugin", options }); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + i18n?: InternationalizationOptions; + } +} diff --git a/packages/plugin-logger/README.md b/packages/plugin-logger/README.md index 6f33153d..2e850cfd 100644 --- a/packages/plugin-logger/README.md +++ b/packages/plugin-logger/README.md @@ -44,16 +44,22 @@ its constructor, so it needs no extra dependency. ### Stars module -On framework 6.1 and later, list the module in `modules` in `stars.config` (needs the optional -`@wolfstar/kit` peer): +On framework 6.1 and later, list the module in `modules` in `stars.config` and write its options +under the `logger` key (needs the optional `@wolfstar/kit` peer, 0.2 or later): ```ts // stars.config.ts +import type {} from "@wolfstar/plugin-logger/module"; // types the `logger` key in `defineConfig` + export default defineConfig({ - modules: [["@wolfstar/plugin-logger/module", { level: 20 }]], + modules: ["@wolfstar/plugin-logger/module"], + logger: { level: 20 }, }); ``` +The `[specifier, options]` tuple still works: `modules: [["@wolfstar/plugin-logger/module", { level: 20 }]]`. +Its options are merged over the `logger` key, so they win. + The options are written into the built entry, so they must be JSON-serialisable (`level`, ...). Transports are objects: set them through `ClientOptions.logger.transports`. @@ -65,21 +71,17 @@ options are written inline: ```ts // stars.config.ts export default defineConfig({ - modules: [ - [ - "@wolfstar/plugin-logger/module", - { - level: 20, - evlog: { - env: { service: "bot" }, - sampling: { rates: { debug: 10 } }, - redact: true, - pipeline: { batch: { size: 25 } }, - drain: "./src/evlog-drain.ts", - }, - }, - ], - ], + modules: ["@wolfstar/plugin-logger/module"], + logger: { + level: 20, + evlog: { + env: { service: "bot" }, + sampling: { rates: { debug: 10 } }, + redact: true, + pipeline: { batch: { size: 25 } }, + drain: "./src/evlog-drain.ts", + }, + }, }); ``` diff --git a/packages/plugin-logger/package.json b/packages/plugin-logger/package.json index fd443779..0ab3e0ca 100644 --- a/packages/plugin-logger/package.json +++ b/packages/plugin-logger/package.json @@ -91,14 +91,16 @@ }, "devDependencies": { "@wolfstar/http-framework": "^6.1.0", - "@wolfstar/kit": "^0.1.0", + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0", "consola": "^3.4.2", "evlog": "^2.29.0", "winston": "^3.19.0" }, "peerDependencies": { "@wolfstar/http-framework": "^3.4.0 || ^5.0.0 || ^6.0.0", - "@wolfstar/kit": "^0.1.0", + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0", "consola": "^3.0.0", "evlog": "^2.30.0", "winston": "^3.0.0" @@ -107,6 +109,9 @@ "@wolfstar/kit": { "optional": true }, + "@wolfstar/schema": { + "optional": true + }, "consola": { "optional": true }, diff --git a/packages/plugin-logger/src/module.ts b/packages/plugin-logger/src/module.ts index 037dcb4d..30728db3 100644 --- a/packages/plugin-logger/src/module.ts +++ b/packages/plugin-logger/src/module.ts @@ -101,9 +101,12 @@ export type EvlogSource = string | { from: string; export?: string }; /** * The Stars module: listing `@wolfstar/plugin-logger/module` in `modules` in `stars.config` registers the logger - * plugin with the options written there. + * plugin with the options written under its `logger` key. * * @remarks + * The `[specifier, options]` tuple of `modules` still works: its options are merged over the `logger` key, so they + * win. + * * The options are written into the built entry, so they have to be JSON-serialisable (`level`, ...). Transports are * objects: set them through `ClientOptions.logger.transports`. * @@ -115,25 +118,22 @@ export type EvlogSource = string | { from: string; export?: string }; * @example * ```ts * // stars.config.ts - * export default defineConfig({ modules: [['@wolfstar/plugin-logger/module', { level: 20 }]] }); + * export default defineConfig({ modules: ['@wolfstar/plugin-logger/module'], logger: { level: 20 } }); * ``` * * @example * ```ts * // stars.config.ts * export default defineConfig({ - * modules: [ - * [ - * '@wolfstar/plugin-logger/module', - * { evlog: { env: { service: 'bot' }, pipeline: true, drain: './src/evlog-drain.ts' } } - * ] - * ] + * modules: ['@wolfstar/plugin-logger/module'], + * logger: { evlog: { env: { service: 'bot' }, pipeline: true, drain: './src/evlog-drain.ts' } } * }); * ``` */ export default defineModule({ meta: { name: "@wolfstar/plugin-logger", + configKey: "logger", compatibility: { framework: ">=6.1.0" }, }, setup({ evlog, ...options }, ctx) { @@ -152,6 +152,12 @@ export default defineModule({ }, }); +declare module "@wolfstar/schema" { + interface StarsConfig { + logger?: LoggerModuleOptions; + } +} + function resolveSource(source: EvlogSource, root: string): { from: string; export?: string } { const { from, export: exportName } = typeof source === "string" ? { from: source } : source; diff --git a/packages/plugin-scheduled-tasks/README.md b/packages/plugin-scheduled-tasks/README.md index 7970b2cd..9a5989a7 100644 --- a/packages/plugin-scheduled-tasks/README.md +++ b/packages/plugin-scheduled-tasks/README.md @@ -31,22 +31,24 @@ pnpm add @wolfstar/plugin-scheduled-tasks @wolfstar/kit ### Registering the plugin -With the `stars` CLI, list the package in `modules`: +With the `stars` CLI, list the package in `modules` and write its options under the `scheduledTasks` +key (needs `@wolfstar/kit` 0.2 or later): ```ts // stars.config.ts import { defineConfig } from "@wolfstar/http-framework/config"; +import type {} from "@wolfstar/plugin-scheduled-tasks"; // types the `scheduledTasks` key in `defineConfig` export default defineConfig({ - modules: [ - [ - "@wolfstar/plugin-scheduled-tasks", - { queue: "tasks", bull: { connection: { host: "localhost", port: 6379 } } }, - ], - ], + modules: ["@wolfstar/plugin-scheduled-tasks"], + scheduledTasks: { queue: "tasks", bull: { connection: { host: "localhost", port: 6379 } } }, }); ``` +The `[specifier, options]` tuple still works: +`modules: [["@wolfstar/plugin-scheduled-tasks", { queue: "tasks" }]]`. Its options are merged over the +`scheduledTasks` key, so they win. + Options written in `stars.config` end up in the built entry, so they have to be JSON-serialisable. Without the CLI, or to pass an `ioredis` instance, give the plugin to the client: diff --git a/packages/plugin-scheduled-tasks/package.json b/packages/plugin-scheduled-tasks/package.json index fc8ed955..d7f99f37 100644 --- a/packages/plugin-scheduled-tasks/package.json +++ b/packages/plugin-scheduled-tasks/package.json @@ -67,11 +67,18 @@ "@redstardev/unplugin-version-injector": "^0.0.2", "@sapphire/pieces": "^4.4.1", "@wolfstar/http-framework": "^6.1.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependencies": { "@wolfstar/http-framework": "^6.1.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" + }, + "peerDependenciesMeta": { + "@wolfstar/schema": { + "optional": true + } }, "engines": { "node": ">=20.0.0" diff --git a/packages/plugin-scheduled-tasks/src/module.ts b/packages/plugin-scheduled-tasks/src/module.ts index 39aee1db..887e899a 100644 --- a/packages/plugin-scheduled-tasks/src/module.ts +++ b/packages/plugin-scheduled-tasks/src/module.ts @@ -3,9 +3,12 @@ import type { ScheduledTasksPluginOptions } from "./lib/types/ScheduledTaskTypes /** * The Stars module: listing the package in `modules` in `stars.config` registers the runtime plugin with the options - * written there. + * written under its `scheduledTasks` key. * * @remarks + * The `[specifier, options]` tuple of `modules` still works: its options are merged over the `scheduledTasks` key, so + * they win. + * * The options are written into the built entry, so they have to be JSON-serialisable: `bull.connection` is a plain * connection object here. To pass an `ioredis` instance or the `ready` function, use `ClientOptions.tasks` or `scheduledTasks()`. * @@ -13,13 +16,15 @@ import type { ScheduledTasksPluginOptions } from "./lib/types/ScheduledTaskTypes * ```ts * // stars.config.ts * export default defineConfig({ - * modules: [['@wolfstar/plugin-scheduled-tasks', { bull: { connection: { host: 'localhost', port: 6379 } } }]] + * modules: ['@wolfstar/plugin-scheduled-tasks'], + * scheduledTasks: { bull: { connection: { host: 'localhost', port: 6379 } } } * }); * ``` */ export const scheduledTasksModule = defineModule({ meta: { name: "@wolfstar/plugin-scheduled-tasks", + configKey: "scheduledTasks", compatibility: { framework: ">=6.1.0" }, }, setup(options, ctx) { @@ -27,3 +32,9 @@ export const scheduledTasksModule = defineModule({ ctx.addImports("@wolfstar/plugin-scheduled-tasks"); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + scheduledTasks?: ScheduledTasksPluginOptions; + } +} diff --git a/packages/plugin-scheduled-tasks/tests/module.test.ts b/packages/plugin-scheduled-tasks/tests/module.test.ts index 896e4f1b..624619e9 100644 --- a/packages/plugin-scheduled-tasks/tests/module.test.ts +++ b/packages/plugin-scheduled-tasks/tests/module.test.ts @@ -9,6 +9,7 @@ describe("module", () => { test("GIVEN the default export THEN it is a module for framework 6.1 and later", () => { expect(scheduledTasksModule.meta).toEqual({ name: "@wolfstar/plugin-scheduled-tasks", + configKey: "scheduledTasks", compatibility: { framework: ">=6.1.0" }, }); }); diff --git a/packages/plugin-sharder/README.md b/packages/plugin-sharder/README.md index 2bb81261..46c03c7d 100644 --- a/packages/plugin-sharder/README.md +++ b/packages/plugin-sharder/README.md @@ -314,7 +314,7 @@ export default defineConfig({ }); ``` -The module registers no plugin and takes no options: you still construct the `ShardManager` yourself. +The module registers no plugin and takes no options: you still construct the `ShardManager` yourself. It owns the `sharder` key of `stars.config` (reserved for future options), so no other module can claim it. ## RFC alignment diff --git a/packages/plugin-sharder/package.json b/packages/plugin-sharder/package.json index c58f9ed7..25e68508 100644 --- a/packages/plugin-sharder/package.json +++ b/packages/plugin-sharder/package.json @@ -65,14 +65,19 @@ "@sapphire/result": "^2.8.0" }, "devDependencies": { - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependencies": { - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependenciesMeta": { "@wolfstar/kit": { "optional": true + }, + "@wolfstar/schema": { + "optional": true } }, "engines": { diff --git a/packages/plugin-sharder/src/module.ts b/packages/plugin-sharder/src/module.ts index 6dcedb6f..5723730f 100644 --- a/packages/plugin-sharder/src/module.ts +++ b/packages/plugin-sharder/src/module.ts @@ -1,12 +1,26 @@ import { defineModule } from "@wolfstar/kit"; +/** + * The options of the module: none yet. The `sharder` key of `stars.config` is reserved for them. + */ +export type SharderModuleOptions = Record; + /** * The Stars module: listing `@wolfstar/plugin-sharder/module` in `modules` in `stars.config` adds the package to the * auto imports. Shards are still started by constructing a `ShardManager` yourself. + * + * @remarks + * The module owns the `sharder` key of `stars.config`, which takes no options for now. */ -export default defineModule({ - meta: { name: "@wolfstar/plugin-sharder" }, +export default defineModule({ + meta: { name: "@wolfstar/plugin-sharder", configKey: "sharder" }, setup(_options, ctx) { ctx.addImports("@wolfstar/plugin-sharder"); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + sharder?: SharderModuleOptions; + } +} diff --git a/packages/plugin-subcommands-advanced/README.md b/packages/plugin-subcommands-advanced/README.md index 62ae8d4a..d47d7275 100644 --- a/packages/plugin-subcommands-advanced/README.md +++ b/packages/plugin-subcommands-advanced/README.md @@ -28,7 +28,8 @@ pnpm add @wolfstar/http-framework @wolfstar/plugin-subcommands-advanced On framework 6.1 and later, list the module in `modules` in `stars.config` (needs the optional `@wolfstar/kit` peer). The module itself takes no options; the package's behaviour is still configured -through `ClientOptions.subcommandsAdvanced` (for example `nameCommandsAutogenerated`): +through `ClientOptions.subcommandsAdvanced` (for example `nameCommandsAutogenerated`). It owns the +`subcommandsAdvanced` key of `stars.config` (reserved for future options), so no other module can claim it: ```ts // stars.config.ts diff --git a/packages/plugin-subcommands-advanced/package.json b/packages/plugin-subcommands-advanced/package.json index 6b57a9c1..ff4b1148 100644 --- a/packages/plugin-subcommands-advanced/package.json +++ b/packages/plugin-subcommands-advanced/package.json @@ -73,15 +73,20 @@ "devDependencies": { "@wolfstar/http-framework": "^6.2.0", "@wolfstar/http-framework-test-utils": "^4.0.2", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependencies": { "@wolfstar/http-framework": "^3.1.0 || ^5.0.0 || ^6.0.0", - "@wolfstar/kit": "^0.1.0" + "@wolfstar/kit": "^0.2.0", + "@wolfstar/schema": "^0.9.0" }, "peerDependenciesMeta": { "@wolfstar/kit": { "optional": true + }, + "@wolfstar/schema": { + "optional": true } }, "engines": { diff --git a/packages/plugin-subcommands-advanced/src/module.ts b/packages/plugin-subcommands-advanced/src/module.ts index 868c4301..5ae93cc9 100644 --- a/packages/plugin-subcommands-advanced/src/module.ts +++ b/packages/plugin-subcommands-advanced/src/module.ts @@ -1,10 +1,18 @@ import { defineModule } from "@wolfstar/kit"; +/** + * The options of the module: none yet. The `subcommandsAdvanced` key of `stars.config` is reserved for them. + */ +export type SubcommandsAdvancedModuleOptions = Record; + /** * The Stars module: listing `@wolfstar/plugin-subcommands-advanced/module` in `modules` in `stars.config` registers * the subcommands plugin. The module itself takes no options; the package's behaviour is still configured through * `ClientOptions.subcommandsAdvanced` (for example `nameCommandsAutogenerated`). * + * @remarks + * The module owns the `subcommandsAdvanced` key of `stars.config`, which takes no options for now. + * * @example * ```ts * // stars.config.ts @@ -13,12 +21,19 @@ import { defineModule } from "@wolfstar/kit"; * }); * ``` */ -export default defineModule({ +export default defineModule({ meta: { name: "@wolfstar/plugin-subcommands-advanced", + configKey: "subcommandsAdvanced", compatibility: { framework: ">=6.1.0" }, }, setup(options, ctx) { ctx.addPlugin({ from: "@wolfstar/plugin-subcommands-advanced/plugin", options }); }, }); + +declare module "@wolfstar/schema" { + interface StarsConfig { + subcommandsAdvanced?: SubcommandsAdvancedModuleOptions; + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8b1f94a..827fde2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -205,6 +205,12 @@ importers: '@vitest/coverage-v8': specifier: ^5.0.3 version: 5.0.3(vitest@5.0.3) + '@wolfstar/kit': + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) cz-conventional-changelog: specifier: ^3.3.0 version: 3.3.0(@types/node@22.15.21)(typescript@7.0.2) @@ -277,10 +283,13 @@ importers: version: 0.0.2(@nuxt/kit@3.21.11(magicast@0.5.5))(@nuxt/schema@3.21.11)(rolldown@1.2.12)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/http-framework': specifier: ^6.1.0 - version: 6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) + version: 6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) packages/plugin-broker: dependencies: @@ -293,13 +302,16 @@ importers: version: 4.4.1 '@wolfstar/http-framework': specifier: ^6.1.0 - version: 6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) + version: 6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) '@wolfstar/plugin-gateway': specifier: workspace:^ version: link:../plugin-gateway + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) ioredis: specifier: ^6.0.0 version: 6.0.0(supports-color@7.2.0) @@ -311,8 +323,11 @@ importers: version: 0.38.56 devDependencies: '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) ioredis: specifier: ^6.0.0 version: 6.0.0(supports-color@7.2.0) @@ -349,10 +364,13 @@ importers: devDependencies: '@wolfstar/http-framework': specifier: ^6.1.0 - version: 6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) + version: 6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) packages/plugin-i18next: dependencies: @@ -383,22 +401,28 @@ importers: devDependencies: '@wolfstar/http-framework': specifier: ^6.1.0 - version: 6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) + version: 6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/i18next-type-generator': specifier: 3.1.5 version: 3.1.5 '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) packages/plugin-logger: devDependencies: '@wolfstar/http-framework': specifier: ^6.1.0 - version: 6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) + version: 6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) consola: specifier: ^3.4.2 version: 3.4.2 @@ -426,10 +450,13 @@ importers: version: 4.4.1 '@wolfstar/http-framework': specifier: ^6.1.0 - version: 6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) + version: 6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) packages/plugin-sharder: dependencies: @@ -438,8 +465,11 @@ importers: version: 2.8.0 devDependencies: '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) packages/plugin-subcommands-advanced: dependencies: @@ -460,8 +490,11 @@ importers: specifier: ^4.0.2 version: 4.0.2(@wolfstar/http-framework@6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)))(vitest@5.0.3) '@wolfstar/kit': - specifier: ^0.1.0 - version: 0.1.1(magicast@0.5.5) + specifier: ^0.2.0 + version: 0.2.0(magicast@0.5.5) + '@wolfstar/schema': + specifier: ^0.9.0 + version: 0.9.0(magicast@0.5.5) packages: @@ -1975,25 +2008,6 @@ packages: '@vue/shared@3.5.43': resolution: {integrity: sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==} - '@wolfstar/cli@2.3.1': - resolution: {integrity: sha512-Txi0HQVRxS/Y/CBOqz80MnOJQCHs4sEcJBo1Qh60z2tv/YLyxJ82oIRXvcP9zQs/s+0xPdN0iXAYJQoqysj9eg==} - engines: {node: '>=22'} - hasBin: true - peerDependencies: - nitro: '>=3.0.0-0' - tsdown: '>=0.15.0' - typescript: '>=5.0.0' - vite: '>=6.0.0' - peerDependenciesMeta: - nitro: - optional: true - tsdown: - optional: true - typescript: - optional: true - vite: - optional: true - '@wolfstar/cli@2.6.0': resolution: {integrity: sha512-CG0H8eDV4GW/iOK/vW4DQp6CpZa6VI/RLb/XuejhlGuCw9byODScVmvPXeX4/ksedU6K7e2c+2f3qgpc/vLAOA==} engines: {node: '>=22'} @@ -2023,11 +2037,6 @@ packages: vitest: optional: true - '@wolfstar/http-framework@6.1.1': - resolution: {integrity: sha512-yyC9Jsopjpyaso0UKssfvagqr+XEJtdUg4mG9tdJwNaMcdNU2zWUTZVmwb/sdxASuEACH2jjUvJV48XEP27p0w==} - engines: {node: '>=20'} - hasBin: true - '@wolfstar/http-framework@6.2.2': resolution: {integrity: sha512-VTUU1lINeN/ng0SMIX9Zv6dWasouzvYCwgZnguGViGbFLwQab64haSZ97ZfhPHZRi0VnzhXN0qJAbO+RP/mq7Q==} engines: {node: '>=20'} @@ -2042,26 +2051,10 @@ packages: engines: {node: '>=20'} hasBin: true - '@wolfstar/kit@0.1.1': - resolution: {integrity: sha512-0dk/A0H1EQy1Lc5X0Rv4TPEZhEoJV1vhGjGnc1RCBZnhkemA61K8+kF2kTR/YHDk3nEmo97NS3GR8K8zNDjiCw==} - engines: {node: '>=20'} - '@wolfstar/kit@0.2.0': resolution: {integrity: sha512-2Xy3gV/LQztOd/FNUqhE0vBR2e2YDYu4ypqNjVuAkkuoXewWlDmmm+8Cveaw8NmA1ya/EuMbjdmZ8qEkhYlsTQ==} engines: {node: '>=20'} - '@wolfstar/nitro-server@0.2.6': - resolution: {integrity: sha512-QnvuDuzSvNd6N6MjnSWle1Gqm+H2dLmfIftYEefpPWn6UTDeIw0npu2aG0cH6B6gYPsEVn5/QkApwqbgs3d2Kw==} - engines: {node: '>=22'} - peerDependencies: - nitro: '>=3.0.0-0' - vite: '>=6.0.0' - peerDependenciesMeta: - nitro: - optional: true - vite: - optional: true - '@wolfstar/nitro-server@0.2.9': resolution: {integrity: sha512-A5MRUjhkTVwHqKq57OIkyk2J3Dmf81p2uIFIXmOQICljuuu3Ml/O6wTLeDXGTUltxUwFtLq3fwek2GLoGmxfqA==} engines: {node: '>=22'} @@ -2074,23 +2067,10 @@ packages: vite: optional: true - '@wolfstar/schema@0.6.0': - resolution: {integrity: sha512-vK0RcEjT+M+hi0yFsgbBQ06XYQNUOWcgbWNgDSezMhjl3wjWIa5Vrt+u4m8hvIcezco3z4Y66sVdChXz95Qo4w==} - engines: {node: '>=20'} - '@wolfstar/schema@0.9.0': resolution: {integrity: sha512-panjxSXHYpmP1r0uZcJg1qgtdqxsADxOqgSPhktB7m75b2W609FplxzcsqFNcBWuoGGPkZeTBRbmATwupLhZNw==} engines: {node: '>=20'} - '@wolfstar/vite-server@0.4.1': - resolution: {integrity: sha512-3Ks5Q349KPN2mRjTW7ftNfH+8WhmdeltsXaTpfvqws3gXGretiAJDd3ovu1228URhBJszz+7dVR9EW/qVQ5WIg==} - engines: {node: '>=22'} - peerDependencies: - vite: '>=6.0.0' - peerDependenciesMeta: - vite: - optional: true - '@wolfstar/vite-server@0.4.4': resolution: {integrity: sha512-A37Y7O3Onq5Gj+phCfzJ3EriHahAaUIXkSPsn7c65E8H19ppeMTbDx0lISVq6YBa/hrdJnogf1HjmXqgeM56WA==} engines: {node: '>=22'} @@ -5367,35 +5347,6 @@ snapshots: '@vue/shared@3.5.43': {} - '@wolfstar/cli@2.3.1(magicast@0.5.5)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@clack/prompts': 1.8.1 - '@sapphire/ts-config': 5.0.3 - '@wolfstar/kit': 0.1.1(magicast@0.5.5) - '@wolfstar/nitro-server': 0.2.6(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - '@wolfstar/schema': 0.6.0(magicast@0.5.5) - '@wolfstar/vite-server': 0.4.1(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - chokidar: 5.0.0 - citty: 0.2.2 - colorette: 2.0.20 - hookable: 6.1.2 - ink: 7.1.1(react@19.3.0) - mlly: 1.8.2 - my-bad: 0.2.10(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - nostics: 1.3.0 - react: 19.3.0 - untun: 0.2.2 - optionalDependencies: - tsdown: 0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1) - typescript: 7.0.2 - vite: 8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1) - transitivePeerDependencies: - - '@types/react' - - bufferutil - - magicast - - react-devtools-core - - utf-8-validate - '@wolfstar/cli@2.6.0(magicast@0.5.5)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@clack/prompts': 1.8.1 @@ -5431,44 +5382,6 @@ snapshots: optionalDependencies: vitest: 5.0.3(@opentelemetry/api@1.9.1)(@types/node@22.15.21)(@vitest/coverage-v8@5.0.3)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - '@wolfstar/http-framework@6.1.1(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@discordjs/builders': 1.14.1 - '@discordjs/collection': 2.1.1 - '@discordjs/rest': 2.6.3 - '@discordjs/util': 1.2.0 - '@sapphire/pieces': 4.4.1 - '@sapphire/result': 2.8.0 - '@sapphire/utilities': 3.18.2 - '@vladfrangu/async_event_emitter': 2.4.7 - '@wolfstar/cli': 2.3.1(magicast@0.5.5)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - '@wolfstar/schema': 0.6.0(magicast@0.5.5) - chokidar: 5.0.0 - discord-api-types: 0.38.56 - mlly: 1.8.2 - unimport: 7.0.2(acorn@8.19.0)(oxc-parser@0.150.0)(rolldown@1.2.12)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - transitivePeerDependencies: - - '@farmfe/core' - - '@rsbuild/core' - - '@rspack/core' - - '@types/react' - - acorn - - bufferutil - - bun-types-no-globals - - esbuild - - magicast - - nitro - - oxc-parser - - react-devtools-core - - rolldown - - rollup - - tsdown - - typescript - - unloader - - utf-8-validate - - vite - - webpack - '@wolfstar/http-framework@6.2.2(acorn@8.19.0)(magicast@0.5.5)(oxc-parser@0.150.0)(rolldown@1.2.12)(tsdown@0.23.0(@arethetypeswrong/core@0.18.5)(oxc-resolver@11.24.2)(publint@0.3.25)(typescript@7.0.2)(unrun@0.3.1))(typescript@7.0.2)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@discordjs/builders': 1.14.1 @@ -5523,13 +5436,6 @@ snapshots: - svelte - vite-plus - '@wolfstar/kit@0.1.1(magicast@0.5.5)': - dependencies: - '@wolfstar/schema': 0.6.0(magicast@0.5.5) - semver: 7.8.5 - transitivePeerDependencies: - - magicast - '@wolfstar/kit@0.2.0(magicast@0.5.5)': dependencies: '@wolfstar/schema': 0.9.0(magicast@0.5.5) @@ -5537,17 +5443,6 @@ snapshots: transitivePeerDependencies: - magicast - '@wolfstar/nitro-server@0.2.6(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@wolfstar/schema': 0.6.0(magicast@0.5.5) - '@wolfstar/vite-server': 0.4.1(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1)) - chokidar: 5.0.0 - picomatch: 4.0.7 - optionalDependencies: - vite: 8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1) - transitivePeerDependencies: - - magicast - '@wolfstar/nitro-server@0.2.9(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@wolfstar/schema': 0.9.0(magicast@0.5.5) @@ -5559,13 +5454,6 @@ snapshots: transitivePeerDependencies: - magicast - '@wolfstar/schema@0.6.0(magicast@0.5.5)': - dependencies: - c12: 3.3.4(magicast@0.5.5) - nostics: 1.3.0 - transitivePeerDependencies: - - magicast - '@wolfstar/schema@0.9.0(magicast@0.5.5)': dependencies: c12: 3.3.4(magicast@0.5.5) @@ -5573,15 +5461,6 @@ snapshots: transitivePeerDependencies: - magicast - '@wolfstar/vite-server@0.4.1(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@wolfstar/schema': 0.6.0(magicast@0.5.5) - srvx: 1.0.5 - optionalDependencies: - vite: 8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1) - transitivePeerDependencies: - - magicast - '@wolfstar/vite-server@0.4.4(magicast@0.5.5)(vite@8.3.3(@types/node@22.15.21)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@wolfstar/schema': 0.9.0(magicast@0.5.5) diff --git a/tests/module-config-keys.test.ts b/tests/module-config-keys.test.ts new file mode 100644 index 00000000..9c4eb224 --- /dev/null +++ b/tests/module-config-keys.test.ts @@ -0,0 +1,132 @@ +import { setupModules, type SetupModulesOptions, type StarsModule } from "@wolfstar/kit"; +import { BUILT_IN_CONFIG_KEYS } from "@wolfstar/schema"; +import { describe, expect, test, vi } from "vitest"; +import apiModule from "../packages/plugin-api/src/module"; +import brokerModule from "../packages/plugin-broker/src/module"; +import cacheModule from "../packages/plugin-cache/src/module"; +import gatewayModule from "../packages/plugin-gateway/src/module"; +import i18nextModule from "../packages/plugin-i18next/src/module"; +import loggerModule from "../packages/plugin-logger/src/module"; +import { scheduledTasksModule } from "../packages/plugin-scheduled-tasks/src/module"; +import sharderModule from "../packages/plugin-sharder/src/module"; +import subcommandsModule from "../packages/plugin-subcommands-advanced/src/module"; + +// The `stars.config` key each module owns. A key is part of the public configuration: renaming one breaks every +// project that writes it, so a change here is a breaking one. +const modules: [name: string, key: string, module: StarsModule][] = [ + ["@wolfstar/plugin-api", "api", apiModule], + ["@wolfstar/plugin-broker", "broker", brokerModule], + ["@wolfstar/plugin-cache", "cache", cacheModule], + ["@wolfstar/plugin-gateway", "gateway", gatewayModule], + ["@wolfstar/plugin-i18next", "i18n", i18nextModule], + ["@wolfstar/plugin-logger", "logger", loggerModule], + ["@wolfstar/plugin-scheduled-tasks", "scheduledTasks", scheduledTasksModule], + ["@wolfstar/plugin-sharder", "sharder", sharderModule], + ["@wolfstar/plugin-subcommands-advanced", "subcommandsAdvanced", subcommandsModule], +]; + +function install( + entries: { module: StarsModule; options?: Record }[], + moduleOptions: Record, +) { + const specifiers = new Map(entries.map(({ module }) => [module.meta.name, module])); + const options: SetupModulesOptions = { + config: { + root: "/project", + modules: entries.map(({ module, options }) => ({ specifier: module.meta.name, options })), + moduleOptions, + } as unknown as SetupModulesOptions["config"], + hooks: { hook: vi.fn(), callHook: vi.fn() }, + load: async (specifier) => specifiers.get(specifier), + }; + + return setupModules(options); +} + +describe("module config keys", () => { + test.each(modules)("GIVEN %s THEN it owns the %s key", (name, key, module) => { + expect(module.meta).toMatchObject({ name, configKey: key }); + }); + + test("GIVEN every module THEN the keys are unique and none is a built-in key of stars.config", () => { + const keys = modules.map(([, key]) => key); + + expect(new Set(keys).size).toBe(keys.length); + for (const key of keys) expect(BUILT_IN_CONFIG_KEYS).not.toContain(key); + }); + + test("GIVEN every module installed together THEN each key is claimed by exactly one of them", async () => { + const runtime = await install( + modules.map(([, , module]) => ({ module })), + {}, + ); + + expect([...runtime.configKeys].sort()).toEqual(modules.map(([, key]) => key).sort()); + }); + + describe.each([ + { + key: "api", + module: apiModule, + plugin: "@wolfstar/plugin-api/plugin", + options: { prefix: "/api" }, + }, + { + key: "broker", + module: brokerModule, + plugin: "@wolfstar/plugin-broker/plugin", + options: { stream: "wolfstar:events", group: "workers" }, + }, + { + key: "i18n", + module: i18nextModule, + plugin: "@wolfstar/plugin-i18next/plugin", + options: { defaultLanguageDirectory: "./languages" }, + }, + { + key: "logger", + module: loggerModule, + plugin: "@wolfstar/plugin-logger/plugin", + options: { level: 20 }, + }, + { + key: "scheduledTasks", + module: scheduledTasksModule, + plugin: "@wolfstar/plugin-scheduled-tasks/plugin", + options: { queue: "tasks", bull: { connection: { host: "localhost", port: 6379 } } }, + }, + ])("the $key key", ({ key, module, plugin, options }) => { + test("GIVEN options under the key THEN setup registers the plugin with them", async () => { + const runtime = await install([{ module }], { [key]: options }); + + expect(runtime.plugins).toContainEqual(expect.objectContaining({ from: plugin, options })); + }); + + test("GIVEN the same option in the tuple and under the key THEN the tuple wins", async () => { + const [name, value] = Object.entries(options)[0]!; + const runtime = await install([{ module, options: { [name]: "from-tuple" } }], { + [key]: options, + }); + + expect(runtime.plugins).toContainEqual( + expect.objectContaining({ + from: plugin, + options: { ...options, [name]: "from-tuple" }, + }), + ); + expect(value).not.toBe("from-tuple"); + }); + + test("GIVEN no options anywhere THEN the module is still installed", async () => { + const runtime = await install([{ module }], {}); + + expect(runtime.modules.map((installed) => installed.name)).toContain(module.meta.name); + }); + }); + + test("GIVEN a key that is not a plain object THEN the module is rejected", async () => { + await expect(install([{ module: apiModule }], { api: "/api" })).rejects.toMatchObject({ + code: "MODULE_INVALID", + }); + }); +}); diff --git a/tests/module-entries.test.ts b/tests/module-entries.test.ts index a168ba48..ecfe5970 100644 --- a/tests/module-entries.test.ts +++ b/tests/module-entries.test.ts @@ -48,8 +48,16 @@ describe.each(entries)("$manifest.name module entries", ({ manifest, tsdown, has }); test("declares @wolfstar/kit as an optional peer and a devDependency", () => { - expect(manifest.peerDependencies?.["@wolfstar/kit"]).toBe("^0.1.0"); + expect(manifest.peerDependencies?.["@wolfstar/kit"]).toBe("^0.2.0"); expect(manifest.peerDependenciesMeta?.["@wolfstar/kit"]?.optional).toBe(true); expect(manifest.devDependencies?.["@wolfstar/kit"]).toBeDefined(); }); + + // `module.d.ts` augments `StarsConfig` from `@wolfstar/schema` to type the module's `configKey`, which only + // resolves for a consumer when the package can reach `@wolfstar/schema`. + test("declares @wolfstar/schema as an optional peer and a devDependency", () => { + expect(manifest.peerDependencies?.["@wolfstar/schema"]).toBeDefined(); + expect(manifest.peerDependenciesMeta?.["@wolfstar/schema"]?.optional).toBe(true); + expect(manifest.devDependencies?.["@wolfstar/schema"]).toBeDefined(); + }); }); From a2911e513a37bda752286026567a506d583e7bce Mon Sep 17 00:00:00 2001 From: RedStar Date: Tue, 20 Oct 2026 18:38:16 +0200 Subject: [PATCH 2/2] chore: ignore the @wolfstar/schema augmentation peer in knip --- knip.json | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/knip.json b/knip.json index a5c15929..cc620953 100644 --- a/knip.json +++ b/knip.json @@ -12,11 +12,13 @@ ] }, "packages/*": { - "project": ["src/**/*.ts"] + "project": ["src/**/*.ts"], + "ignoreDependencies": ["@wolfstar/schema"] }, "packages/plugin-logger": { "entry": ["src/assertions.ts"], - "project": ["src/**/*.ts"] + "project": ["src/**/*.ts"], + "ignoreDependencies": ["@wolfstar/schema"] }, "packages/plugin-broker": { "entry": ["src/index.ts", "tests/types/*.ts"], @@ -25,7 +27,8 @@ }, "packages/plugin-cache": { "entry": ["src/index.ts", "tests/types/*.ts"], - "project": ["src/**/*.ts", "tests/types/*.ts"] + "project": ["src/**/*.ts", "tests/types/*.ts"], + "ignoreDependencies": ["@wolfstar/schema"] }, "packages/plugin-gateway": { "project": ["src/**/*.ts"], @@ -34,11 +37,11 @@ "packages/plugin-scheduled-tasks": { "entry": ["src/index.ts", "tests/types/*.ts"], "project": ["src/**/*.ts", "tests/types/*.ts"], - "ignoreDependencies": ["@sapphire/pieces"] + "ignoreDependencies": ["@sapphire/pieces", "@wolfstar/schema"] }, "packages/plugin-i18next": { "project": ["src/**/*.ts"], - "ignoreDependencies": ["@wolfstar/i18next-type-generator"] + "ignoreDependencies": ["@wolfstar/i18next-type-generator", "@wolfstar/schema"] } } }