@saykit/carbon 0.0.0-beta-20260309151609

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.
@@ -0,0 +1,66 @@
1
+ import { APIInteraction, BaseCommand, BaseComponent, Modal, Plugin } from "@buape/carbon";
2
+ import { Say } from "saykit";
3
+
4
+ //#region src/constants.d.ts
5
+ declare const kSay: unique symbol;
6
+ //#endregion
7
+ //#region src/extensions/base-interaction.d.ts
8
+ declare module '@buape/carbon' {
9
+ interface BaseInteraction<T extends APIInteraction> {
10
+ get say(): Say;
11
+ [kSay]: Say;
12
+ }
13
+ }
14
+ declare function applyBaseInteractionExtension(): () => void;
15
+ //#endregion
16
+ //#region src/extensions/guild.d.ts
17
+ declare module '@buape/carbon' {
18
+ interface Guild {
19
+ get say(): Say;
20
+ [kSay]: Say;
21
+ }
22
+ }
23
+ declare function applyGuildExtension(): () => void;
24
+ //#endregion
25
+ //#region src/mixers/with-say.d.ts
26
+ type Keys = 'name' | 'description' | 'label' | 'title' | 'placeholder' | 'content' | 'options' | 'components' | 'subcommands' | 'subcommandGroups';
27
+ type AbstractConstructor<Args extends any[] = any[], Instance extends object = object> = abstract new (...args: Args) => Instance;
28
+ type SayProps<T> = Pick<T, Extract<keyof T, Keys>>;
29
+ /**
30
+ * Enhances a {@link BaseCommand} subclass with support for localisation.
31
+ *
32
+ * @param Base Abstract command constructor to extend.
33
+ * @returns A new constructor that accepts a {@link Say} instance, a
34
+ * properties-mapping function, and the original constructor arguments.
35
+ */
36
+ declare function withSay<Args extends unknown[], Instance extends BaseCommand>(Base: AbstractConstructor<Args, Instance>): AbstractConstructor<[say: Say, properties: (say: Say) => SayProps<Instance>, ...args: Args], Instance & Partial<Record<Keys, unknown>>>;
37
+ /**
38
+ * Enhances a {@link BaseComponent} or {@link Modal} subclass with
39
+ * support for localisation.
40
+ *
41
+ * @param Base Abstract component or modal constructor to extend.
42
+ * @returns A new constructor that accepts a set of properties.
43
+ */
44
+ declare function withSay<Args extends unknown[], Instance extends BaseComponent | Modal>(Base: AbstractConstructor<Args, Instance>): AbstractConstructor<[properties: SayProps<Instance>, ...args: Args], Instance & Partial<Record<Keys, unknown>>>;
45
+ //#endregion
46
+ //#region src/plugin.d.ts
47
+ /**
48
+ * A Carbon plugin that provides a singleton {@link Say} instance.
49
+ *
50
+ * `SayPlugin` registers a {@link Say} instance globally and
51
+ * applies interaction and guild-level extensions so that commands and
52
+ * other handlers can access localisation utilities directly.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const say = new Say({ ... });
57
+ * const client = new Client({ ... }, { ... }, [new SayPlugin(say)]);
58
+ * ```
59
+ */
60
+ declare class SayPlugin extends Plugin {
61
+ id: string;
62
+ constructor(say: Say);
63
+ }
64
+ //#endregion
65
+ export { SayPlugin, applyBaseInteractionExtension, applyGuildExtension, withSay };
66
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,135 @@
1
+ import { BaseCommand, BaseComponent, BaseInteraction, Guild, Locale, Modal, Plugin } from "@buape/carbon";
2
+
3
+ //#region src/utils/combine-command-options.ts
4
+ const ALLOWED_LOCALES = Object.values(Locale);
5
+ function combineCommandOptions(mappedOptions, baseLocale) {
6
+ const options = mappedOptions[baseLocale];
7
+ const availableLocales = Object.keys(mappedOptions).filter((l) => l !== baseLocale && ALLOWED_LOCALES.includes(l));
8
+ for (const [key, value] of Object.entries(options)) if (key === "name" || key === "description") {
9
+ options[`${key}Localizations`] = {};
10
+ for (const locale of availableLocales) {
11
+ const other = mappedOptions[locale][key];
12
+ options[`${key}Localizations`][locale] = other;
13
+ }
14
+ options[`${key}_localizations`] = options[`${key}Localizations`];
15
+ } else if ((key === "options" || key === "choices") && Array.isArray(value)) for (const [index, option] of Object.entries(value)) {
16
+ const mapped = { [baseLocale]: option };
17
+ for (const locale of availableLocales) mapped[locale] = mappedOptions[locale][key][index];
18
+ const combined = combineCommandOptions(mapped, baseLocale);
19
+ options[key][index] = combined;
20
+ }
21
+ return options;
22
+ }
23
+
24
+ //#endregion
25
+ //#region src/mixers/with-say.ts
26
+ const ClassMap = /* @__PURE__ */ new WeakMap();
27
+ /**
28
+ * Factory function that creates a "withSay" wrapper around a base class.
29
+ *
30
+ * @param Base The base class constructor.
31
+ * @returns A subclass of the given base class with extra for localisation.
32
+ * @throws If the base class is neither a {@link BaseCommand} nor a
33
+ * {@link BaseComponent}.
34
+ */
35
+ function withSay(Base) {
36
+ if (ClassMap.has(Base)) return ClassMap.get(Base);
37
+ if (Base.prototype instanceof BaseCommand) {
38
+ const Derived = createSayCommand(Base);
39
+ ClassMap.set(Base, Derived);
40
+ return Derived;
41
+ }
42
+ if (Base.prototype instanceof BaseComponent || Base === Modal) {
43
+ const Derived = createSayComponent(Base);
44
+ ClassMap.set(Base, Derived);
45
+ return Derived;
46
+ }
47
+ throw new Error("Invalid base class");
48
+ }
49
+ function createSayCommand(Base) {
50
+ class SayCommand extends Base {
51
+ constructor(say, properties, ...args) {
52
+ super(...args);
53
+ const options = combineCommandOptions(say.reduce((acc, [s, l]) => {
54
+ acc[l] = properties(s);
55
+ return acc;
56
+ }, {}), say.locale);
57
+ Object.assign(this, options);
58
+ }
59
+ }
60
+ return SayCommand;
61
+ }
62
+ function createSayComponent(Base) {
63
+ class SayComponent extends Base {
64
+ constructor(properties, ...args) {
65
+ super(...args);
66
+ if (properties) Object.assign(this, properties);
67
+ }
68
+ }
69
+ return SayComponent;
70
+ }
71
+
72
+ //#endregion
73
+ //#region src/constants.ts
74
+ const kSay = Symbol.for("saykit.say");
75
+
76
+ //#endregion
77
+ //#region src/extensions/base-interaction.ts
78
+ function applyBaseInteractionExtension() {
79
+ Object.defineProperty(BaseInteraction.prototype, "say", { get() {
80
+ const say = Reflect.get(globalThis, kSay);
81
+ if (!say) throw new Error("No `say` instance available");
82
+ this[kSay] ??= say.clone();
83
+ const locale = this[kSay].match([this.rawData.locale]);
84
+ this[kSay].activate(locale);
85
+ return this[kSay];
86
+ } });
87
+ return () => {
88
+ Object.defineProperty(BaseInteraction.prototype, "say", { value: void 0 });
89
+ };
90
+ }
91
+
92
+ //#endregion
93
+ //#region src/extensions/guild.ts
94
+ function applyGuildExtension() {
95
+ Object.defineProperty(Guild.prototype, "say", { get() {
96
+ const say = Reflect.get(globalThis, kSay);
97
+ if (!say) throw new Error("No `say` instance available");
98
+ this[kSay] ??= say.clone();
99
+ const locale = this[kSay].match([this.rawData.preferred_locale]);
100
+ this[kSay].activate(locale);
101
+ return this[kSay];
102
+ } });
103
+ return () => {
104
+ Object.defineProperty(Guild.prototype, "say", { value: void 0 });
105
+ };
106
+ }
107
+
108
+ //#endregion
109
+ //#region src/plugin.ts
110
+ /**
111
+ * A Carbon plugin that provides a singleton {@link Say} instance.
112
+ *
113
+ * `SayPlugin` registers a {@link Say} instance globally and
114
+ * applies interaction and guild-level extensions so that commands and
115
+ * other handlers can access localisation utilities directly.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * const say = new Say({ ... });
120
+ * const client = new Client({ ... }, { ... }, [new SayPlugin(say)]);
121
+ * ```
122
+ */
123
+ var SayPlugin = class extends Plugin {
124
+ id = "saykit";
125
+ constructor(say) {
126
+ super();
127
+ Reflect.set(globalThis, kSay, say);
128
+ applyBaseInteractionExtension();
129
+ applyGuildExtension();
130
+ }
131
+ };
132
+
133
+ //#endregion
134
+ export { SayPlugin, withSay };
135
+ //# sourceMappingURL=index.mjs.map
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@saykit/carbon",
3
+ "version": "0.0.0-beta-20260309151609",
4
+ "description": "Carbon Discord framework integration for saykit",
5
+ "keywords": [
6
+ "bot",
7
+ "carbon",
8
+ "discord",
9
+ "i18n",
10
+ "saykit"
11
+ ],
12
+ "homepage": "https://github.com/k0d13/saykit#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/k0d13/saykit/issues"
15
+ },
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/k0d13/saykit.git",
20
+ "directory": "packages/integration-carbon"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "!dist/**/*.map"
25
+ ],
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.mts",
30
+ "default": "./dist/index.mjs"
31
+ }
32
+ },
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "provenance": true
36
+ },
37
+ "devDependencies": {
38
+ "@buape/carbon": "0.14.0",
39
+ "saykit": "^0.0.0-beta-20260309151609"
40
+ },
41
+ "peerDependencies": {
42
+ "@buape/carbon": "*",
43
+ "saykit": "0.0.0-beta-20260309151609"
44
+ },
45
+ "scripts": {
46
+ "check": "tsc --noEmit",
47
+ "build": "tsdown"
48
+ }
49
+ }