@mostfeatured/dbi 0.2.11 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "tslib": "^2.6.3"
16
16
  },
17
17
  "name": "@mostfeatured/dbi",
18
- "version": "0.2.11",
18
+ "version": "0.2.13",
19
19
  "main": "dist/src/index.js",
20
20
  "types": "dist/src/index.d.ts",
21
21
  "typesVersions": {
@@ -100,9 +100,10 @@ function parseStringSelect(dbi: DBI<NamespaceEnums>, dbiName: string, stringSele
100
100
  let minValues = parseInt(stringSelect.getAttribute("min-values"));
101
101
  let maxValues = parseInt(stringSelect.getAttribute("max-values"));
102
102
 
103
- let options = Array.from(stringSelect.querySelectorAll("option")).map(option => {
103
+ // Support both <option> and <select-option> elements (Svelte may output either)
104
+ let options = Array.from(stringSelect.querySelectorAll("option, select-option")).map(option => {
104
105
  return {
105
- label: getCleanTextContent(option),
106
+ label: option.getAttribute("label") || getCleanTextContent(option),
106
107
  value: option.getAttribute("value"),
107
108
  description: option.getAttribute("description"),
108
109
  emoji: option.getAttribute("emoji"),
@@ -125,7 +126,8 @@ function parseNonStringSelect(dbi: DBI<NamespaceEnums>, dbiName: string, userSel
125
126
  let minValues = parseInt(userSelect.getAttribute("min-values"));
126
127
  let maxValues = parseInt(userSelect.getAttribute("max-values"));
127
128
 
128
- let options = Array.from(userSelect.querySelectorAll("option")).map(option => {
129
+ // Support both <option> and <select-option> elements (Svelte may output either)
130
+ let options = Array.from(userSelect.querySelectorAll("option, select-option")).map(option => {
129
131
  return {
130
132
  id: getCleanTextContent(option) || option.getAttribute("id"),
131
133
  type: option.getAttribute("type")
@@ -264,14 +266,19 @@ function parseElement(dbi: DBI<NamespaceEnums>, dbiName: string, element: Elemen
264
266
  case "BUTTON":
265
267
  return parseButton(dbi, dbiName, element);
266
268
  case "STRING-SELECT":
269
+ case "STRING-SELECT-MENU":
267
270
  return parseStringSelect(dbi, dbiName, element);
268
271
  case "USER-SELECT":
272
+ case "USER-SELECT-MENU":
269
273
  return parseNonStringSelect(dbi, dbiName, element, ComponentType.UserSelect);
270
274
  case "ROLE-SELECT":
275
+ case "ROLE-SELECT-MENU":
271
276
  return parseNonStringSelect(dbi, dbiName, element, ComponentType.RoleSelect);
272
277
  case "MENTIONABLE-SELECT":
278
+ case "MENTIONABLE-SELECT-MENU":
273
279
  return parseNonStringSelect(dbi, dbiName, element, ComponentType.MentionableSelect);
274
280
  case "CHANNEL-SELECT":
281
+ case "CHANNEL-SELECT-MENU":
275
282
  return parseNonStringSelect(dbi, dbiName, element, ComponentType.ChannelSelect);
276
283
  case "SECTION":
277
284
  return parseSection(dbi, dbiName, element);
@@ -104,15 +104,28 @@ export async function parseSvelteComponent(source: string, data?: Record<string,
104
104
  attr.type === "Attribute" && attr.name === "name"
105
105
  );
106
106
 
107
- // Check if element has an onclick/onchange handler and get the handler info
107
+ // Check if element has an onclick/onchange/handler and get the handler info
108
108
  let foundHandler: { eventType: string; handlerName: string } | null = null;
109
109
 
110
110
  for (const attr of attributes) {
111
111
  const isEventHandler = attr.type === "EventHandler";
112
112
  const isOnAttribute = attr.type === "Attribute" && attr.name && attr.name.startsWith("on");
113
-
114
- if (isEventHandler || isOnAttribute) {
115
- const eventType = attr.name;
113
+ const isHandlerAttribute = attr.type === "Attribute" && attr.name === "handler";
114
+
115
+ if (isEventHandler || isOnAttribute || isHandlerAttribute) {
116
+ // For "handler" attribute, use the element type to determine eventType
117
+ // button -> onclick, select -> onchange
118
+ let eventType = attr.name;
119
+ if (isHandlerAttribute) {
120
+ const elementName = node.name.toLowerCase();
121
+ if (elementName === "button") {
122
+ eventType = "onclick";
123
+ } else if (elementName.includes("select")) {
124
+ eventType = "onchange";
125
+ } else {
126
+ eventType = "handler"; // fallback
127
+ }
128
+ }
116
129
  let handlerName = "";
117
130
 
118
131
  if (attr.type === "Attribute" && Array.isArray(attr.value)) {
@@ -82,16 +82,24 @@ export async function renderSvelteComponent(
82
82
  }
83
83
 
84
84
  // Add state ref to all elements with name attribute (buttons, selects)
85
+ // This includes both manual names and auto-generated names from svelteParser
85
86
  html = html.replace(/<button([^>]*name="[^"]*"[^>]*)>/g, (match, attrs) => {
86
87
  // Check if it already has data attributes
87
88
  if (attrs.includes('data-1:')) return match;
88
89
  return `<button${attrs} data-1:ref="${stateRefId}">`;
89
90
  });
90
- // Also handle select elements
91
- html = html.replace(/<(string-select|user-select|role-select|channel-select|mentionable-select)([^>]*name="[^"]*"[^>]*)>/g, (match, tag, attrs) => {
91
+ // Also handle select elements (with optional -menu suffix for Svelte compatibility)
92
+ // Supports: string-select, user-select, role-select, channel-select, mentionable-select
93
+ // Both with and without -menu suffix (e.g., string-select-menu or string-select)
94
+ html = html.replace(/<(string-select(?:-menu)?|user-select(?:-menu)?|role-select(?:-menu)?|channel-select(?:-menu)?|mentionable-select(?:-menu)?)([^>]*name="[^"]*"[^>]*)>/g, (match, tag, attrs) => {
92
95
  if (attrs.includes('data-1:')) return match;
93
96
  return `<${tag}${attrs} data-1:ref="${stateRefId}">`;
94
97
  });
98
+ // Handle modal elements with name attribute
99
+ html = html.replace(/<modal([^>]*name="[^"]*"[^>]*)>/g, (match, attrs) => {
100
+ if (attrs.includes('data-1:')) return match;
101
+ return `<modal${attrs} data-1:ref="${stateRefId}">`;
102
+ });
95
103
  }
96
104
 
97
105
  // Parse the rendered HTML to Discord components
package/test/index.ts CHANGED
@@ -3,7 +3,7 @@ import path from "path";
3
3
 
4
4
  const dbi = createDBI("svelte", {
5
5
  discord: {
6
- token: "YOUR_BOT_TOKEN_HERE",
6
+ token: process.env.DISCORD_TOKEN || "",
7
7
  options: {
8
8
  intents: [
9
9
  "GuildMessages",
@@ -26,7 +26,8 @@ dbi.register(({ ChatInput, HTMLComponentsV2 }) => {
26
26
  HTMLComponentsV2({
27
27
  name: "product-showcase",
28
28
  mode: 'svelte',
29
- file: path.join(__dirname, "product-showcase.svelte")
29
+ file: path.join(__dirname, "product-showcase.svelte"),
30
+ onExecute(ctx) {}
30
31
  });
31
32
 
32
33
  // Test command