@rimori/client 1.4.0 → 1.4.4

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 (133) hide show
  1. package/README.md +77 -71
  2. package/dist/cli/scripts/init/dev-registration.d.ts +1 -1
  3. package/dist/cli/scripts/init/dev-registration.js +4 -4
  4. package/dist/cli/scripts/init/main.js +1 -1
  5. package/dist/cli/scripts/init/package-setup.d.ts +1 -1
  6. package/dist/cli/scripts/init/package-setup.js +3 -3
  7. package/dist/cli/scripts/init/router-transformer.js +19 -12
  8. package/dist/cli/scripts/init/vite-config.d.ts +2 -2
  9. package/dist/cli/scripts/init/vite-config.js +2 -2
  10. package/dist/cli/scripts/release/release-config-upload.js +9 -9
  11. package/dist/cli/scripts/release/release-db-update.d.ts +1 -1
  12. package/dist/cli/scripts/release/release-db-update.js +9 -9
  13. package/dist/cli/scripts/release/release-file-upload.js +1 -1
  14. package/dist/cli/scripts/release/release.js +2 -2
  15. package/dist/components/CRUDModal.d.ts +1 -1
  16. package/dist/components/CRUDModal.js +3 -3
  17. package/dist/components/MarkdownEditor.js +16 -16
  18. package/dist/components/Spinner.js +2 -2
  19. package/dist/components/ai/Assistant.js +7 -8
  20. package/dist/components/ai/Avatar.d.ts +2 -2
  21. package/dist/components/ai/Avatar.js +10 -5
  22. package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +5 -6
  23. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +1 -1
  24. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -2
  25. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +1 -2
  26. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +4 -2
  27. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +2 -3
  28. package/dist/components/audio/Playbutton.js +10 -7
  29. package/dist/components/components/ContextMenu.d.ts +1 -1
  30. package/dist/components/components/ContextMenu.js +19 -16
  31. package/dist/components.d.ts +10 -10
  32. package/dist/components.js +10 -10
  33. package/dist/core/controller/AIController.d.ts +2 -2
  34. package/dist/core/controller/AIController.js +12 -12
  35. package/dist/core/controller/ExerciseController.d.ts +2 -2
  36. package/dist/core/controller/ExerciseController.js +2 -2
  37. package/dist/core/controller/ObjectController.js +5 -5
  38. package/dist/core/controller/SettingsController.d.ts +22 -7
  39. package/dist/core/controller/SettingsController.js +73 -8
  40. package/dist/core/controller/SharedContentController.d.ts +3 -3
  41. package/dist/core/controller/SharedContentController.js +38 -20
  42. package/dist/core/controller/VoiceController.js +6 -4
  43. package/dist/core/core.d.ts +15 -15
  44. package/dist/core/core.js +7 -7
  45. package/dist/fromRimori/EventBus.js +23 -23
  46. package/dist/fromRimori/PluginTypes.d.ts +4 -4
  47. package/dist/hooks/UseChatHook.d.ts +3 -3
  48. package/dist/hooks/UseChatHook.js +9 -3
  49. package/dist/index.d.ts +10 -10
  50. package/dist/index.js +9 -9
  51. package/dist/plugin/AccomplishmentHandler.d.ts +5 -5
  52. package/dist/plugin/AccomplishmentHandler.js +31 -27
  53. package/dist/plugin/AudioController.d.ts +1 -1
  54. package/dist/plugin/AudioController.js +6 -6
  55. package/dist/plugin/Logger.js +15 -13
  56. package/dist/plugin/PluginController.d.ts +7 -1
  57. package/dist/plugin/PluginController.js +32 -27
  58. package/dist/plugin/RimoriClient.d.ts +17 -18
  59. package/dist/plugin/RimoriClient.js +31 -31
  60. package/dist/plugin/StandaloneClient.d.ts +1 -1
  61. package/dist/plugin/StandaloneClient.js +35 -16
  62. package/dist/plugin/ThemeSetter.js +4 -4
  63. package/dist/providers/PluginProvider.js +44 -14
  64. package/dist/utils/Language.js +57 -57
  65. package/dist/utils/PluginUtils.js +3 -3
  66. package/dist/utils/difficultyConverter.d.ts +1 -1
  67. package/dist/utils/difficultyConverter.js +1 -1
  68. package/dist/utils/endpoint.js +2 -2
  69. package/dist/worker/WorkerSetup.d.ts +1 -1
  70. package/dist/worker/WorkerSetup.js +6 -6
  71. package/example/docs/devdocs.md +50 -40
  72. package/example/docs/overview.md +1 -1
  73. package/example/docs/userdocs.md +4 -1
  74. package/example/rimori.config.ts +51 -49
  75. package/example/worker/vite.config.ts +3 -3
  76. package/example/worker/worker.ts +2 -2
  77. package/package.json +14 -8
  78. package/prettier.config.js +1 -1
  79. package/src/cli/scripts/init/dev-registration.ts +5 -8
  80. package/src/cli/scripts/init/env-setup.ts +1 -1
  81. package/src/cli/scripts/init/file-operations.ts +1 -1
  82. package/src/cli/scripts/init/html-cleaner.ts +2 -5
  83. package/src/cli/scripts/init/main.ts +16 -13
  84. package/src/cli/scripts/init/package-setup.ts +11 -15
  85. package/src/cli/scripts/init/router-transformer.ts +40 -37
  86. package/src/cli/scripts/init/tailwind-config.ts +17 -26
  87. package/src/cli/scripts/init/vite-config.ts +3 -3
  88. package/src/cli/scripts/release/release-config-upload.ts +11 -11
  89. package/src/cli/scripts/release/release-db-update.ts +12 -12
  90. package/src/cli/scripts/release/release-file-upload.ts +2 -2
  91. package/src/cli/scripts/release/release.ts +4 -4
  92. package/src/cli/types/DatabaseTypes.ts +2 -10
  93. package/src/components/CRUDModal.tsx +64 -48
  94. package/src/components/MarkdownEditor.tsx +58 -27
  95. package/src/components/Spinner.tsx +24 -17
  96. package/src/components/ai/Assistant.tsx +70 -70
  97. package/src/components/ai/Avatar.tsx +17 -14
  98. package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +63 -54
  99. package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +14 -5
  100. package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +75 -74
  101. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +3 -4
  102. package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +109 -94
  103. package/src/components/ai/utils.ts +4 -4
  104. package/src/components/audio/Playbutton.tsx +101 -93
  105. package/src/components/components/ContextMenu.tsx +47 -35
  106. package/src/components.ts +10 -10
  107. package/src/core/controller/AIController.ts +29 -19
  108. package/src/core/controller/ExerciseController.ts +16 -23
  109. package/src/core/controller/ObjectController.ts +15 -10
  110. package/src/core/controller/SettingsController.ts +89 -16
  111. package/src/core/controller/SharedContentController.ts +80 -44
  112. package/src/core/controller/VoiceController.ts +10 -8
  113. package/src/core/core.ts +15 -16
  114. package/src/fromRimori/EventBus.ts +76 -47
  115. package/src/fromRimori/PluginTypes.ts +26 -17
  116. package/src/fromRimori/readme.md +2 -2
  117. package/src/hooks/UseChatHook.ts +25 -15
  118. package/src/index.ts +10 -10
  119. package/src/plugin/AccomplishmentHandler.ts +53 -35
  120. package/src/plugin/AudioController.ts +18 -12
  121. package/src/plugin/Logger.ts +28 -21
  122. package/src/plugin/PluginController.ts +60 -44
  123. package/src/plugin/RimoriClient.ts +102 -72
  124. package/src/plugin/StandaloneClient.ts +51 -24
  125. package/src/plugin/ThemeSetter.ts +5 -5
  126. package/src/providers/PluginProvider.tsx +90 -36
  127. package/src/style.scss +3 -3
  128. package/src/utils/Language.ts +58 -58
  129. package/src/utils/PluginUtils.ts +16 -20
  130. package/src/utils/difficultyConverter.ts +2 -2
  131. package/src/utils/endpoint.ts +3 -2
  132. package/src/worker/WorkerSetup.ts +8 -9
  133. package/tsconfig.json +2 -4
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { createClient } from '@supabase/supabase-js';
11
11
  import { EventBus } from '../fromRimori/EventBus';
12
- import { RimoriClient } from "./RimoriClient";
12
+ import { RimoriClient } from './RimoriClient';
13
13
  import { StandaloneClient } from './StandaloneClient';
14
14
  import { setTheme } from './ThemeSetter';
15
15
  import { Logger } from './Logger';
@@ -36,11 +36,15 @@ export class PluginController {
36
36
  }
37
37
  initMessageChannel(worker = false) {
38
38
  const listener = (event) => {
39
- console.log("[PluginController] window message", { origin: event.origin, data: event.data });
39
+ console.log('[PluginController] window message', { origin: event.origin, data: event.data });
40
40
  const { type, pluginId, queryParams, rimoriInfo } = event.data || {};
41
41
  const [transferredPort] = event.ports || [];
42
- if (type !== "rimori:init" || !transferredPort || pluginId !== this.pluginId) {
43
- console.log("[PluginController] message ignored (not init or wrong plugin)", { type, pluginId, hasPort: !!transferredPort });
42
+ if (type !== 'rimori:init' || !transferredPort || pluginId !== this.pluginId) {
43
+ console.log('[PluginController] message ignored (not init or wrong plugin)', {
44
+ type,
45
+ pluginId,
46
+ hasPort: !!transferredPort,
47
+ });
44
48
  return;
45
49
  }
46
50
  this.queryParams = queryParams || {};
@@ -49,7 +53,7 @@ export class PluginController {
49
53
  if (rimoriInfo) {
50
54
  this.rimoriInfo = rimoriInfo;
51
55
  this.supabase = createClient(rimoriInfo.url, rimoriInfo.key, {
52
- accessToken: () => Promise.resolve(rimoriInfo.token)
56
+ accessToken: () => Promise.resolve(rimoriInfo.token),
53
57
  });
54
58
  }
55
59
  // Handle messages from parent
@@ -75,38 +79,38 @@ export class PluginController {
75
79
  setTheme(theme);
76
80
  }
77
81
  // Forward plugin events to parent (only after MessageChannel is ready)
78
- EventBus.on("*", (ev) => {
82
+ EventBus.on('*', (ev) => {
79
83
  var _a;
80
- if (ev.sender === this.pluginId && !ev.topic.startsWith("self.")) {
84
+ if (ev.sender === this.pluginId && !ev.topic.startsWith('self.')) {
81
85
  (_a = this.port) === null || _a === void 0 ? void 0 : _a.postMessage({ event: ev });
82
86
  }
83
87
  });
84
88
  // Mark MessageChannel as ready and process pending requests
85
89
  this.isMessageChannelReady = true;
86
90
  // Process any pending requests
87
- this.pendingRequests.forEach(request => request());
91
+ this.pendingRequests.forEach((request) => request());
88
92
  this.pendingRequests = [];
89
93
  };
90
94
  if (worker) {
91
95
  self.onmessage = listener;
92
96
  }
93
97
  else {
94
- window.addEventListener("message", listener);
98
+ window.addEventListener('message', listener);
95
99
  }
96
100
  this.sendHello(worker);
97
101
  }
98
102
  sendHello(isWorker = false) {
99
103
  try {
100
- const payload = { type: "rimori:hello", pluginId: this.pluginId };
104
+ const payload = { type: 'rimori:hello', pluginId: this.pluginId };
101
105
  if (isWorker) {
102
106
  self.postMessage(payload);
103
107
  }
104
108
  else {
105
- window.parent.postMessage(payload, "*");
109
+ window.parent.postMessage(payload, '*');
106
110
  }
107
111
  }
108
112
  catch (e) {
109
- console.error("[PluginController] Error sending hello:", e);
113
+ console.error('[PluginController] Error sending hello:', e);
110
114
  }
111
115
  }
112
116
  static getInstance(pluginId_1) {
@@ -118,7 +122,7 @@ export class PluginController {
118
122
  PluginController.instance = new PluginController(pluginId, standalone);
119
123
  PluginController.client = yield RimoriClient.getInstance(PluginController.instance);
120
124
  //only init logger in workers and on main plugin pages
121
- if (PluginController.instance.getQueryParam("applicationMode") !== "sidebar") {
125
+ if (PluginController.instance.getQueryParam('applicationMode') !== 'sidebar') {
122
126
  Logger.getInstance(PluginController.client);
123
127
  }
124
128
  }
@@ -159,8 +163,8 @@ export class PluginController {
159
163
  sender: this.pluginId,
160
164
  topic: 'global.supabase.requestAccess',
161
165
  data: {},
162
- debug: false
163
- }
166
+ debug: false,
167
+ },
164
168
  };
165
169
  return new Promise((resolve) => {
166
170
  // Listen for the response
@@ -170,7 +174,7 @@ export class PluginController {
170
174
  if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.topic) === 'global.supabase.requestAccess' && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.eventId) === eventId) {
171
175
  this.rimoriInfo = event.data.data;
172
176
  this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
173
- accessToken: () => Promise.resolve(this.getToken())
177
+ accessToken: () => Promise.resolve(this.getToken()),
174
178
  });
175
179
  self.onmessage = originalOnMessage; // Restore original handler
176
180
  resolve({ supabase: this.supabase, info: this.rimoriInfo });
@@ -185,10 +189,11 @@ export class PluginController {
185
189
  }
186
190
  else {
187
191
  // In main thread context, use EventBus
188
- const { data } = yield EventBus.request(this.pluginId, "global.supabase.requestAccess");
192
+ const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
193
+ console.log({ data });
189
194
  this.rimoriInfo = data;
190
195
  this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
191
- accessToken: () => Promise.resolve(this.getToken())
196
+ accessToken: () => Promise.resolve(this.getToken()),
192
197
  });
193
198
  }
194
199
  }
@@ -202,12 +207,12 @@ export class PluginController {
202
207
  }
203
208
  // If we don't have rimoriInfo, request it
204
209
  if (!this.rimoriInfo) {
205
- const { data } = yield EventBus.request(this.pluginId, "global.supabase.requestAccess");
210
+ const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
206
211
  this.rimoriInfo = data;
207
212
  return this.rimoriInfo.token;
208
213
  }
209
214
  // If token is expired, request fresh access
210
- const { data } = yield EventBus.request(this.pluginId, "global.supabase.requestAccess");
215
+ const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
211
216
  this.rimoriInfo.token = data.token;
212
217
  this.rimoriInfo.expiration = data.expiration;
213
218
  return this.rimoriInfo.token;
@@ -220,27 +225,27 @@ export class PluginController {
220
225
  */
221
226
  getSupabaseUrl() {
222
227
  if (!this.rimoriInfo) {
223
- throw new Error("Supabase info not found");
228
+ throw new Error('Supabase info not found');
224
229
  }
225
230
  return this.rimoriInfo.url;
226
231
  }
227
232
  getBackendUrl() {
228
233
  if (!this.rimoriInfo) {
229
- throw new Error("Rimori info not found");
234
+ throw new Error('Rimori info not found');
230
235
  }
231
236
  return this.rimoriInfo.backendUrl;
232
237
  }
233
238
  getGlobalEventTopic(preliminaryTopic) {
234
239
  var _a, _b;
235
- if (preliminaryTopic.startsWith("global.")) {
240
+ if (preliminaryTopic.startsWith('global.')) {
236
241
  return preliminaryTopic;
237
242
  }
238
- if (preliminaryTopic.startsWith("self.")) {
243
+ if (preliminaryTopic.startsWith('self.')) {
239
244
  return preliminaryTopic;
240
245
  }
241
- const topicParts = preliminaryTopic.split(".");
246
+ const topicParts = preliminaryTopic.split('.');
242
247
  if (topicParts.length === 3) {
243
- if (!topicParts[0].startsWith("pl") && topicParts[0] !== "global") {
248
+ if (!topicParts[0].startsWith('pl') && topicParts[0] !== 'global') {
244
249
  throw new Error("The event topic must start with the plugin id or 'global'.");
245
250
  }
246
251
  return preliminaryTopic;
@@ -248,7 +253,7 @@ export class PluginController {
248
253
  else if (topicParts.length > 3) {
249
254
  throw new Error(`The event topic must consist of 3 parts. <pluginId>.<topic area>.<action>. Received: ${preliminaryTopic}`);
250
255
  }
251
- const topicRoot = (_b = (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b : "global";
256
+ const topicRoot = (_b = (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b : 'global';
252
257
  return `${topicRoot}.${preliminaryTopic}`;
253
258
  }
254
259
  }
@@ -1,19 +1,18 @@
1
- import { PostgrestQueryBuilder } from "@supabase/postgrest-js";
2
- import { GenericSchema } from "@supabase/supabase-js/dist/module/lib/types";
3
- import { Message, OnLLMResponse } from "../core/controller/AIController";
4
- import { ObjectRequest } from "../core/controller/ObjectController";
5
- import { UserInfo } from "../core/controller/SettingsController";
6
- import { SharedContent, SharedContentFilter, SharedContentObjectRequest } from "../core/controller/SharedContentController";
7
- import { CreateExerciseParams } from "../core/controller/ExerciseController";
8
- import { EventBusMessage, EventHandler, EventPayload } from "../fromRimori/EventBus";
9
- import { ActivePlugin, MainPanelAction, Plugin, Tool } from "../fromRimori/PluginTypes";
10
- import { AccomplishmentPayload } from "./AccomplishmentHandler";
11
- import { PluginController } from "./PluginController";
12
- import { ClientServerOptions } from "@supabase/postgrest-js/dist/cjs/types/common/common";
1
+ import { PostgrestQueryBuilder } from '@supabase/postgrest-js';
2
+ import { GenericSchema } from '@supabase/supabase-js/dist/module/lib/types';
3
+ import { Message, OnLLMResponse } from '../core/controller/AIController';
4
+ import { ObjectRequest } from '../core/controller/ObjectController';
5
+ import { UserInfo } from '../core/controller/SettingsController';
6
+ import { SharedContent, SharedContentFilter, SharedContentObjectRequest } from '../core/controller/SharedContentController';
7
+ import { CreateExerciseParams } from '../core/controller/ExerciseController';
8
+ import { EventBusMessage, EventHandler, EventPayload } from '../fromRimori/EventBus';
9
+ import { ActivePlugin, MainPanelAction, Plugin, Tool } from '../fromRimori/PluginTypes';
10
+ import { AccomplishmentPayload } from './AccomplishmentHandler';
11
+ import { PluginController } from './PluginController';
13
12
  interface Db {
14
13
  from: {
15
- <TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, Table, TableName>;
16
- <ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, View, ViewName>;
14
+ <TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
15
+ <ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
17
16
  };
18
17
  /**
19
18
  * The table prefix for of database tables of the plugin.
@@ -205,10 +204,10 @@ export declare class RimoriClient {
205
204
  */
206
205
  update: <T = any>(id: string, content: Partial<SharedContent<T>>) => Promise<SharedContent<T>>;
207
206
  /**
208
- * Complete a shared content item.
209
- * @param contentType The type of shared content to complete. E.g. assignments, exercises, etc.
210
- * @param assignmentId The id of the shared content item to complete.
211
- */
207
+ * Complete a shared content item.
208
+ * @param contentType The type of shared content to complete. E.g. assignments, exercises, etc.
209
+ * @param assignmentId The id of the shared content item to complete.
210
+ */
212
211
  complete: (contentType: string, assignmentId: string) => Promise<void>;
213
212
  /**
214
213
  /**
@@ -7,14 +7,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { generateText, streamChatGPT } from "../core/controller/AIController";
11
- import { generateObject } from "../core/controller/ObjectController";
12
- import { SettingsController } from "../core/controller/SettingsController";
13
- import { SharedContentController } from "../core/controller/SharedContentController";
14
- import { getSTTResponse, getTTSResponse } from "../core/controller/VoiceController";
15
- import { ExerciseController } from "../core/controller/ExerciseController";
16
- import { EventBus } from "../fromRimori/EventBus";
17
- import { AccomplishmentHandler } from "./AccomplishmentHandler";
10
+ import { generateText, streamChatGPT } from '../core/controller/AIController';
11
+ import { generateObject } from '../core/controller/ObjectController';
12
+ import { SettingsController } from '../core/controller/SettingsController';
13
+ import { SharedContentController, } from '../core/controller/SharedContentController';
14
+ import { getSTTResponse, getTTSResponse } from '../core/controller/VoiceController';
15
+ import { ExerciseController } from '../core/controller/ExerciseController';
16
+ import { EventBus } from '../fromRimori/EventBus';
17
+ import { AccomplishmentHandler } from './AccomplishmentHandler';
18
18
  export class RimoriClient {
19
19
  constructor(supabase, info, pluginController) {
20
20
  this.event = {
@@ -50,7 +50,7 @@ export class RimoriClient {
50
50
  */
51
51
  on: (topic, callback) => {
52
52
  const topics = Array.isArray(topic) ? topic : [topic];
53
- return EventBus.on(topics.map(t => this.pluginController.getGlobalEventTopic(t)), callback);
53
+ return EventBus.on(topics.map((t) => this.pluginController.getGlobalEventTopic(t)), callback);
54
54
  },
55
55
  /**
56
56
  * Subscribe to an event once.
@@ -67,7 +67,7 @@ export class RimoriClient {
67
67
  */
68
68
  respond: (topic, data) => {
69
69
  const topics = Array.isArray(topic) ? topic : [topic];
70
- EventBus.respond(this.plugin.pluginId, topics.map(t => this.pluginController.getGlobalEventTopic(t)), data);
70
+ EventBus.respond(this.plugin.pluginId, topics.map((t) => this.pluginController.getGlobalEventTopic(t)), data);
71
71
  },
72
72
  /**
73
73
  * Emit an accomplishment.
@@ -91,18 +91,18 @@ export class RimoriClient {
91
91
  * @param text Optional text to be used for the action like for example text that the translator would look up.
92
92
  */
93
93
  emitSidebarAction: (pluginId, actionKey, text) => {
94
- this.event.emit("global.sidebar.triggerAction", { plugin_id: pluginId, action_key: actionKey, text });
94
+ this.event.emit('global.sidebar.triggerAction', { plugin_id: pluginId, action_key: actionKey, text });
95
95
  },
96
96
  onMainPanelAction: (callback) => {
97
97
  // this needs to be a emit and on because the main panel action is triggered by the user and not by the plugin
98
- this.event.emit("action.requestMain");
99
- this.event.on("action.requestMain", ({ data }) => callback(data));
100
- }
98
+ this.event.emit('action.requestMain');
99
+ this.event.on('action.requestMain', ({ data }) => callback(data));
100
+ },
101
101
  };
102
102
  this.navigation = {
103
103
  toDashboard: () => {
104
- this.event.emit("global.navigation.triggerToDashboard");
105
- }
104
+ this.event.emit('global.navigation.triggerToDashboard');
105
+ },
106
106
  };
107
107
  this.ai = {
108
108
  getText: (messages, tools) => __awaiter(this, void 0, void 0, function* () {
@@ -113,7 +113,7 @@ export class RimoriClient {
113
113
  const token = yield this.pluginController.getToken();
114
114
  streamChatGPT(this.pluginController.getBackendUrl(), messages, tools || [], onMessage, token);
115
115
  }),
116
- getVoice: (text_1, ...args_1) => __awaiter(this, [text_1, ...args_1], void 0, function* (text, voice = "alloy", speed = 1, language) {
116
+ getVoice: (text_1, ...args_1) => __awaiter(this, [text_1, ...args_1], void 0, function* (text, voice = 'alloy', speed = 1, language) {
117
117
  const token = yield this.pluginController.getToken();
118
118
  return getTTSResponse(this.pluginController.getBackendUrl(), { input: text, voice, speed, language }, token);
119
119
  }),
@@ -130,8 +130,8 @@ export class RimoriClient {
130
130
  this.runtime = {
131
131
  fetchBackend: (url, options) => __awaiter(this, void 0, void 0, function* () {
132
132
  const token = yield this.pluginController.getToken();
133
- return fetch(this.pluginController.getBackendUrl() + url, Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), { 'Authorization': `Bearer ${token}` }) }));
134
- })
133
+ return fetch(this.pluginController.getBackendUrl() + url, Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), { Authorization: `Bearer ${token}` }) }));
134
+ }),
135
135
  };
136
136
  this.community = {
137
137
  /**
@@ -192,10 +192,10 @@ export class RimoriClient {
192
192
  return yield this.sharedContentController.updateSharedContent(id, content);
193
193
  }),
194
194
  /**
195
- * Complete a shared content item.
196
- * @param contentType The type of shared content to complete. E.g. assignments, exercises, etc.
197
- * @param assignmentId The id of the shared content item to complete.
198
- */
195
+ * Complete a shared content item.
196
+ * @param contentType The type of shared content to complete. E.g. assignments, exercises, etc.
197
+ * @param assignmentId The id of the shared content item to complete.
198
+ */
199
199
  complete: (contentType, assignmentId) => __awaiter(this, void 0, void 0, function* () {
200
200
  return yield this.sharedContentController.completeSharedContent(contentType, assignmentId);
201
201
  }),
@@ -214,8 +214,8 @@ export class RimoriClient {
214
214
  */
215
215
  remove: (id) => __awaiter(this, void 0, void 0, function* () {
216
216
  return yield this.sharedContentController.removeSharedContent(id);
217
- })
218
- }
217
+ }),
218
+ },
219
219
  };
220
220
  this.exercise = {
221
221
  /**
@@ -246,7 +246,7 @@ export class RimoriClient {
246
246
  this.rimoriInfo = info;
247
247
  this.superbase = supabase;
248
248
  this.pluginController = pluginController;
249
- this.settingsController = new SettingsController(supabase, info.pluginId);
249
+ this.settingsController = new SettingsController(supabase, info.pluginId, info.guild);
250
250
  this.sharedContentController = new SharedContentController(this.superbase, this);
251
251
  this.exerciseController = new ExerciseController(supabase, pluginController);
252
252
  this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
@@ -276,7 +276,7 @@ export class RimoriClient {
276
276
  mainPanelPlugin: this.rimoriInfo.mainPanelPlugin,
277
277
  sidePanelPlugin: this.rimoriInfo.sidePanelPlugin,
278
278
  };
279
- }
279
+ },
280
280
  };
281
281
  }
282
282
  /**
@@ -301,11 +301,11 @@ export class RimoriClient {
301
301
  }
302
302
  getTableName(table) {
303
303
  if (/[A-Z]/.test(table)) {
304
- throw new Error("Table name cannot include uppercase letters. Please use snake_case for table names.");
304
+ throw new Error('Table name cannot include uppercase letters. Please use snake_case for table names.');
305
305
  }
306
- if (table.startsWith("global_")) {
307
- return table.replace("global_", "");
306
+ if (table.startsWith('global_')) {
307
+ return table.replace('global_', '');
308
308
  }
309
- return this.db.tablePrefix + "_" + table;
309
+ return this.db.tablePrefix + '_' + table;
310
310
  }
311
311
  }
@@ -1,4 +1,4 @@
1
- import { SupabaseClient } from "@supabase/supabase-js";
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
2
  export interface StandaloneConfig {
3
3
  url: string;
4
4
  key: string;
@@ -7,9 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { createClient } from "@supabase/supabase-js";
11
- import { EventBus } from "../fromRimori/EventBus";
12
- import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from "../utils/endpoint";
10
+ import { createClient } from '@supabase/supabase-js';
11
+ import { EventBus } from '../fromRimori/EventBus';
12
+ import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from '../utils/endpoint';
13
13
  export class StandaloneClient {
14
14
  constructor(config) {
15
15
  this.supabase = createClient(config.url, config.key);
@@ -18,8 +18,10 @@ export class StandaloneClient {
18
18
  static getInstance() {
19
19
  return __awaiter(this, void 0, void 0, function* () {
20
20
  if (!StandaloneClient.instance) {
21
- const config = yield fetch("https://app.rimori.se/config.json").then(res => res.json()).catch(err => {
22
- console.warn("Error fetching config.json, using default values", err);
21
+ const config = yield fetch('https://app.rimori.se/config.json')
22
+ .then((res) => res.json())
23
+ .catch((err) => {
24
+ console.warn('Error fetching config.json, using default values', err);
23
25
  });
24
26
  StandaloneClient.instance = new StandaloneClient({
25
27
  url: (config === null || config === void 0 ? void 0 : config.SUPABASE_URL) || DEFAULT_ENDPOINT,
@@ -45,33 +47,50 @@ export class StandaloneClient {
45
47
  return __awaiter(this, void 0, void 0, function* () {
46
48
  const { error } = yield this.supabase.auth.signInWithPassword({ email, password });
47
49
  if (error) {
48
- console.error("Login failed:", error);
50
+ console.error('Login failed:', error);
49
51
  return false;
50
52
  }
51
- console.log("Successfully logged in");
53
+ console.log('Successfully logged in');
52
54
  return true;
53
55
  });
54
56
  }
55
57
  static initListeners(pluginId) {
56
58
  return __awaiter(this, void 0, void 0, function* () {
57
- console.warn("The plugin seams to not be running inside the Rimori platform. Switching to development standalone mode.");
59
+ console.warn('The plugin seams to not be running inside the Rimori platform. Switching to development standalone mode.');
58
60
  // console.log("event that needs to be handled", event);
59
61
  const { supabase, config } = yield StandaloneClient.getInstance();
60
62
  // EventBus.on("*", async (event) => {
61
- EventBus.respond("standalone", "global.supabase.requestAccess", () => __awaiter(this, void 0, void 0, function* () {
63
+ EventBus.respond('standalone', 'global.supabase.requestAccess', () => __awaiter(this, void 0, void 0, function* () {
62
64
  var _a;
63
65
  const session = yield supabase.auth.getSession();
64
- console.log("session", session);
66
+ console.log('session', session);
65
67
  // Call the NestJS backend endpoint instead of the Supabase edge function
68
+ // get current guild id if any
69
+ let guildId = null;
70
+ try {
71
+ const { data: { user }, } = yield supabase.auth.getUser();
72
+ if (user) {
73
+ const { data: profile } = yield supabase
74
+ .from('profiles')
75
+ .select('current_guild_id')
76
+ .eq('user_id', user.id)
77
+ .maybeSingle();
78
+ guildId = (profile === null || profile === void 0 ? void 0 : profile.current_guild_id) || null;
79
+ }
80
+ }
81
+ catch (_) {
82
+ guildId = null;
83
+ }
66
84
  const response = yield fetch(`${config.backendUrl}/plugin/token`, {
67
85
  method: 'POST',
68
86
  headers: {
69
87
  'Content-Type': 'application/json',
70
- 'Authorization': `Bearer ${(_a = session.data.session) === null || _a === void 0 ? void 0 : _a.access_token}`
88
+ Authorization: `Bearer ${(_a = session.data.session) === null || _a === void 0 ? void 0 : _a.access_token}`,
71
89
  },
72
90
  body: JSON.stringify({
73
- pluginId: pluginId
74
- })
91
+ pluginId: pluginId,
92
+ guildId: guildId,
93
+ }),
75
94
  });
76
95
  if (!response.ok) {
77
96
  const errorText = yield response.text();
@@ -88,9 +107,9 @@ export class StandaloneClient {
88
107
  expiration: new Date(Date.now() + 1000 * 60 * 60 * 1.5), // 1.5 hours
89
108
  };
90
109
  }));
91
- EventBus.on("*", (event) => __awaiter(this, void 0, void 0, function* () {
92
- console.log("[standalone] would send event to parent", event);
93
- }), ["standalone"]);
110
+ EventBus.on('*', (event) => __awaiter(this, void 0, void 0, function* () {
111
+ console.log('[standalone] would send event to parent', event);
112
+ }), ['standalone']);
94
113
  });
95
114
  }
96
115
  }
@@ -1,9 +1,9 @@
1
1
  export function setTheme(theme) {
2
- document.documentElement.classList.add("dark:text-gray-200");
2
+ document.documentElement.classList.add('dark:text-gray-200');
3
3
  if (isDarkTheme(theme)) {
4
- document.documentElement.setAttribute("data-theme", "dark");
5
- document.documentElement.classList.add('dark', "dark:bg-gray-950");
6
- document.documentElement.style.background = "hsl(var(--background))";
4
+ document.documentElement.setAttribute('data-theme', 'dark');
5
+ document.documentElement.classList.add('dark', 'dark:bg-gray-950');
6
+ document.documentElement.style.background = 'hsl(var(--background))';
7
7
  }
8
8
  }
9
9
  export function isDarkTheme(theme) {
@@ -19,24 +19,24 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
19
19
  const [standaloneClient, setStandaloneClient] = useState(false);
20
20
  const [applicationMode, setApplicationMode] = useState(null);
21
21
  const [theme, setTheme] = useState(null);
22
- const isSidebar = applicationMode === "sidebar";
23
- const isSettings = applicationMode === "settings";
22
+ const isSidebar = applicationMode === 'sidebar';
23
+ const isSettings = applicationMode === 'settings';
24
24
  useEffect(() => {
25
25
  initEventBus(pluginId);
26
26
  // Check if we're in an iframe context - if not, we're standalone
27
27
  const standaloneDetected = window === window.parent;
28
28
  if (standaloneDetected && !standaloneClient) {
29
- StandaloneClient.getInstance().then(client => {
29
+ StandaloneClient.getInstance().then((client) => {
30
30
  client.needsLogin().then((needLogin) => setStandaloneClient(needLogin ? client : true));
31
31
  });
32
32
  }
33
33
  if ((!standaloneDetected && !plugin) || (standaloneDetected && standaloneClient === true)) {
34
- PluginController.getInstance(pluginId, standaloneDetected).then(client => {
34
+ PluginController.getInstance(pluginId, standaloneDetected).then((client) => {
35
35
  setPlugin(client);
36
36
  // Get applicationMode and theme from MessageChannel query params
37
37
  if (!standaloneDetected) {
38
- const mode = client.getQueryParam("applicationMode");
39
- const themeParam = client.getQueryParam("rm_theme");
38
+ const mode = client.getQueryParam('applicationMode');
39
+ const themeParam = client.getQueryParam('rm_theme');
40
40
  setApplicationMode(mode);
41
41
  setTheme(themeParam);
42
42
  }
@@ -71,13 +71,13 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
71
71
  return () => body.removeEventListener('resize', handleResize);
72
72
  }, [plugin]);
73
73
  if (standaloneClient instanceof StandaloneClient) {
74
- return _jsx(StandaloneAuth, { onLogin: (email, password) => __awaiter(void 0, void 0, void 0, function* () {
74
+ return (_jsx(StandaloneAuth, { onLogin: (email, password) => __awaiter(void 0, void 0, void 0, function* () {
75
75
  if (yield standaloneClient.login(email, password))
76
76
  setStandaloneClient(true);
77
- }) });
77
+ }) }));
78
78
  }
79
79
  if (!plugin) {
80
- return "";
80
+ return '';
81
81
  }
82
82
  return (_jsxs(PluginContext.Provider, { value: plugin, children: [!(settings === null || settings === void 0 ? void 0 : settings.disableContextMenu) && !isSidebar && !isSettings && _jsx(ContextMenu, { client: plugin }), children] }));
83
83
  };
@@ -103,12 +103,12 @@ function getUrlParam(name) {
103
103
  }
104
104
  function initEventBus(pluginId) {
105
105
  // For now, use URL fallback for EventBus naming - this will be updated once MessageChannel is ready
106
- const isSidebar = getUrlParam("applicationMode") === "sidebar";
107
- EventBusHandler.getInstance("Plugin EventBus " + pluginId + " " + (isSidebar ? "sidebar" : "main"));
106
+ const isSidebar = getUrlParam('applicationMode') === 'sidebar';
107
+ EventBusHandler.getInstance('Plugin EventBus ' + pluginId + ' ' + (isSidebar ? 'sidebar' : 'main'));
108
108
  }
109
109
  function StandaloneAuth({ onLogin }) {
110
- const [user, setUser] = useState("");
111
- const [password, setPassword] = useState("");
110
+ const [user, setUser] = useState('');
111
+ const [password, setPassword] = useState('');
112
112
  return (_jsx("div", { style: {
113
113
  position: 'fixed',
114
114
  inset: 0,
@@ -116,7 +116,37 @@ function StandaloneAuth({ onLogin }) {
116
116
  alignItems: 'center',
117
117
  justifyContent: 'center',
118
118
  backgroundColor: 'rgba(0, 0, 0, 0.5)',
119
- }, children: _jsxs("div", { style: { backgroundColor: '#343534', padding: '1rem', borderRadius: '0.5rem', width: '500px', flexDirection: 'column', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: [_jsx("p", { style: { fontSize: '2rem', fontWeight: 'bold', marginBottom: '1rem', textAlign: 'center' }, children: "Rimori Login" }), _jsx("p", { style: { marginBottom: '1rem', textAlign: 'center' }, children: "Please login with your Rimori developer account for this plugin to be able to access the Rimori platform the same it will operate in the Rimori platform." }), _jsx("input", { style: { marginBottom: '1rem', width: '100%', padding: '0.5rem', borderRadius: '0.5rem', border: 'none', backgroundColor: '#444444' }, type: "email", placeholder: "Email", onChange: (e) => setUser(e.target.value) }), _jsx("input", { style: { marginBottom: '1rem', width: '100%', padding: '0.5rem', borderRadius: '0.5rem', border: 'none', backgroundColor: '#444444' }, type: "password", placeholder: "Password", onChange: (e) => setPassword(e.target.value) }), _jsx("button", { style: { marginBottom: '1rem', width: '100%', padding: '0.5rem', borderRadius: '0.5rem', border: 'none', backgroundColor: '#928358' }, onClick: () => {
119
+ }, children: _jsxs("div", { style: {
120
+ backgroundColor: '#343534',
121
+ padding: '1rem',
122
+ borderRadius: '0.5rem',
123
+ width: '500px',
124
+ flexDirection: 'column',
125
+ display: 'flex',
126
+ alignItems: 'center',
127
+ justifyContent: 'center',
128
+ }, children: [_jsx("p", { style: { fontSize: '2rem', fontWeight: 'bold', marginBottom: '1rem', textAlign: 'center' }, children: "Rimori Login" }), _jsx("p", { style: { marginBottom: '1rem', textAlign: 'center' }, children: "Please login with your Rimori developer account for this plugin to be able to access the Rimori platform the same it will operate in the Rimori platform." }), _jsx("input", { style: {
129
+ marginBottom: '1rem',
130
+ width: '100%',
131
+ padding: '0.5rem',
132
+ borderRadius: '0.5rem',
133
+ border: 'none',
134
+ backgroundColor: '#444444',
135
+ }, type: "email", placeholder: "Email", onChange: (e) => setUser(e.target.value) }), _jsx("input", { style: {
136
+ marginBottom: '1rem',
137
+ width: '100%',
138
+ padding: '0.5rem',
139
+ borderRadius: '0.5rem',
140
+ border: 'none',
141
+ backgroundColor: '#444444',
142
+ }, type: "password", placeholder: "Password", onChange: (e) => setPassword(e.target.value) }), _jsx("button", { style: {
143
+ marginBottom: '1rem',
144
+ width: '100%',
145
+ padding: '0.5rem',
146
+ borderRadius: '0.5rem',
147
+ border: 'none',
148
+ backgroundColor: '#928358',
149
+ }, onClick: () => {
120
150
  onLogin(user, password);
121
151
  }, children: "Login" })] }) }));
122
152
  }