@rimori/client 2.4.0-next.4 → 2.4.0-next.6

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 (35) hide show
  1. package/dist/cli/scripts/init/dev-registration.js +4 -2
  2. package/dist/cli/scripts/init/main.js +1 -0
  3. package/dist/controller/SettingsController.d.ts +1 -1
  4. package/dist/controller/SharedContentController.d.ts +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/plugin/CommunicationHandler.d.ts +3 -10
  7. package/dist/plugin/CommunicationHandler.js +15 -69
  8. package/dist/plugin/RimoriClient.d.ts +11 -208
  9. package/dist/plugin/RimoriClient.js +16 -312
  10. package/dist/plugin/StandaloneClient.d.ts +1 -1
  11. package/dist/plugin/StandaloneClient.js +3 -2
  12. package/dist/plugin/module/AIModule.d.ts +49 -0
  13. package/dist/plugin/module/AIModule.js +81 -0
  14. package/dist/plugin/module/DbModule.d.ts +30 -0
  15. package/dist/plugin/module/DbModule.js +51 -0
  16. package/dist/plugin/module/EventModule.d.ts +99 -0
  17. package/dist/plugin/module/EventModule.js +162 -0
  18. package/dist/{controller/ExerciseController.d.ts → plugin/module/ExerciseModule.d.ts} +20 -16
  19. package/dist/{controller/ExerciseController.js → plugin/module/ExerciseModule.js} +27 -20
  20. package/dist/plugin/module/PluginModule.d.ts +76 -0
  21. package/dist/plugin/module/PluginModule.js +88 -0
  22. package/package.json +4 -3
  23. package/src/cli/scripts/init/dev-registration.ts +4 -2
  24. package/src/cli/scripts/init/main.ts +1 -0
  25. package/src/controller/SettingsController.ts +1 -1
  26. package/src/controller/SharedContentController.ts +1 -1
  27. package/src/index.ts +2 -2
  28. package/src/plugin/CommunicationHandler.ts +17 -79
  29. package/src/plugin/RimoriClient.ts +25 -368
  30. package/src/plugin/StandaloneClient.ts +5 -3
  31. package/src/plugin/module/AIModule.ts +77 -0
  32. package/src/plugin/module/DbModule.ts +67 -0
  33. package/src/plugin/module/EventModule.ts +192 -0
  34. package/src/{controller/ExerciseController.ts → plugin/module/ExerciseModule.ts} +43 -29
  35. package/src/plugin/module/PluginModule.ts +114 -0
@@ -7,7 +7,7 @@ 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';
10
+ // import { createClient } from '@supabase/supabase-js';
11
11
  import path from 'path';
12
12
  import * as readline from 'readline';
13
13
  import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from '../../../utils/endpoint.js';
@@ -112,7 +112,9 @@ export function authenticateWithSupabase(_a) {
112
112
  // Initialize Supabase client (you may need to adjust the URL and key)
113
113
  const supabaseUrl = process.env.SUPABASE_URL || DEFAULT_ENDPOINT;
114
114
  const supabaseKey = process.env.SUPABASE_ANON_KEY || DEFAULT_ANON_KEY;
115
- const supabase = createClient(supabaseUrl, supabaseKey);
115
+ throw new Error('Authentication is disabled until new developer platform is released.');
116
+ // const supabase = createClient(supabaseUrl, supabaseKey);
117
+ const supabase = {};
116
118
  try {
117
119
  const { data, error } = yield supabase.auth.signInWithPassword({
118
120
  email,
@@ -82,6 +82,7 @@ function main() {
82
82
  updateGitignore();
83
83
  }
84
84
  else {
85
+ throw new Error('Registration is disabled until new developer platform is released.');
85
86
  // Step 1: Get user credentials
86
87
  const credentials = yield askForCredentials();
87
88
  console.log('');
@@ -1,4 +1,4 @@
1
- import { SupabaseClient } from '@supabase/supabase-js';
1
+ import { SupabaseClient } from '../plugin/CommunicationHandler';
2
2
  import { LanguageLevel } from '../utils/difficultyConverter';
3
3
  import { Guild } from '../plugin/CommunicationHandler';
4
4
  export interface Buddy {
@@ -1,4 +1,4 @@
1
- import { SupabaseClient } from '@supabase/supabase-js';
1
+ import { SupabaseClient } from '../plugin/CommunicationHandler';
2
2
  import { RimoriClient } from '../plugin/RimoriClient';
3
3
  import { ObjectRequest } from './ObjectController';
4
4
  export interface SharedContentObjectRequest extends ObjectRequest {
package/dist/index.d.ts CHANGED
@@ -10,9 +10,9 @@ export { AudioController } from './controller/AudioController';
10
10
  export { Translator } from './controller/TranslationController';
11
11
  export type { TOptions } from 'i18next';
12
12
  export type { SharedContent, SharedContentObjectRequest } from './controller/SharedContentController';
13
- export type { Exercise } from './controller/ExerciseController';
13
+ export type { Exercise } from './plugin/module/ExerciseModule';
14
14
  export type { UserInfo, Language, UserRole } from './controller/SettingsController';
15
15
  export type { Message, ToolInvocation } from './controller/AIController';
16
- export type { TriggerAction } from './controller/ExerciseController';
16
+ export type { TriggerAction } from './plugin/module/ExerciseModule';
17
17
  export type { MacroAccomplishmentPayload, MicroAccomplishmentPayload } from './controller/AccomplishmentController';
18
18
  export type { EventBusMessage } from './fromRimori/EventBus';
@@ -1,6 +1,7 @@
1
- import { SupabaseClient } from '@supabase/supabase-js';
2
1
  import { UserInfo } from '../controller/SettingsController';
3
2
  import { ActivePlugin, Plugin } from '../fromRimori/PluginTypes';
3
+ import { PostgrestClient } from '@supabase/postgrest-js';
4
+ export type SupabaseClient = PostgrestClient;
4
5
  export interface Guild {
5
6
  allowUserPluginSettings: boolean;
6
7
  city: string | null;
@@ -53,19 +54,11 @@ export declare class RimoriCommunicationHandler {
53
54
  private sendHello;
54
55
  private sendFinishedInit;
55
56
  getQueryParam(key: string): string | null;
57
+ private getSupabase;
56
58
  getClient(): Promise<{
57
59
  supabase: SupabaseClient;
58
60
  info: RimoriInfo;
59
61
  }>;
60
- getToken(): Promise<string>;
61
- /**
62
- * Gets the Supabase URL.
63
- * @returns The Supabase URL.
64
- * @deprecated All endpoints should use the backend URL instead.
65
- */
66
- getSupabaseUrl(): string;
67
- getBackendUrl(): string;
68
- getGlobalEventTopic(preliminaryTopic: string): string;
69
62
  /**
70
63
  * Handles updates to RimoriInfo from rimori-main.
71
64
  * Updates the cached info and Supabase client, then notifies all registered callbacks.
@@ -7,8 +7,8 @@ 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
10
  import { EventBus } from '../fromRimori/EventBus';
11
+ import { PostgrestClient } from '@supabase/postgrest-js';
12
12
  export class RimoriCommunicationHandler {
13
13
  constructor(pluginId, standalone) {
14
14
  this.port = null;
@@ -45,9 +45,7 @@ export class RimoriCommunicationHandler {
45
45
  // Initialize Supabase client immediately with provided info
46
46
  if (rimoriInfo) {
47
47
  this.rimoriInfo = rimoriInfo;
48
- this.supabase = createClient(rimoriInfo.url, rimoriInfo.key, {
49
- accessToken: () => Promise.resolve(rimoriInfo.token),
50
- });
48
+ this.supabase = this.getSupabase(rimoriInfo.url, rimoriInfo.key, rimoriInfo.token);
51
49
  }
52
50
  // Handle messages from parent
53
51
  this.port.onmessage = ({ data }) => {
@@ -133,6 +131,16 @@ export class RimoriCommunicationHandler {
133
131
  getQueryParam(key) {
134
132
  return this.queryParams[key] || null;
135
133
  }
134
+ getSupabase(url, key, token) {
135
+ var _a;
136
+ return new PostgrestClient(`${url}/rest/v1`, {
137
+ schema: (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.dbSchema,
138
+ headers: {
139
+ apikey: key,
140
+ Authorization: `Bearer ${token}`,
141
+ },
142
+ });
143
+ }
136
144
  getClient() {
137
145
  return __awaiter(this, void 0, void 0, function* () {
138
146
  // Return cached client if valid
@@ -174,9 +182,7 @@ export class RimoriCommunicationHandler {
174
182
  var _a, _b;
175
183
  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) {
176
184
  this.rimoriInfo = event.data.data;
177
- this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
178
- accessToken: () => Promise.resolve(this.getToken()),
179
- });
185
+ this.supabase = this.getSupabase(this.rimoriInfo.url, this.rimoriInfo.key, this.rimoriInfo.token);
180
186
  self.onmessage = originalOnMessage; // Restore original handler
181
187
  resolve({ supabase: this.supabase, info: this.rimoriInfo });
182
188
  }
@@ -193,70 +199,12 @@ export class RimoriCommunicationHandler {
193
199
  const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
194
200
  // console.log({ data });
195
201
  this.rimoriInfo = data;
196
- this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
197
- accessToken: () => Promise.resolve(this.getToken()),
198
- });
202
+ this.supabase = this.getSupabase(this.rimoriInfo.url, this.rimoriInfo.key, this.rimoriInfo.token);
199
203
  }
200
204
  }
201
205
  return { supabase: this.supabase, info: this.rimoriInfo };
202
206
  });
203
207
  }
204
- getToken() {
205
- return __awaiter(this, void 0, void 0, function* () {
206
- if (this.rimoriInfo && this.rimoriInfo.expiration && this.rimoriInfo.expiration > new Date()) {
207
- return this.rimoriInfo.token;
208
- }
209
- // If we don't have rimoriInfo, request it
210
- if (!this.rimoriInfo) {
211
- const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
212
- this.rimoriInfo = data;
213
- return this.rimoriInfo.token;
214
- }
215
- // If token is expired, request fresh access
216
- const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
217
- this.rimoriInfo.token = data.token;
218
- this.rimoriInfo.expiration = data.expiration;
219
- return this.rimoriInfo.token;
220
- });
221
- }
222
- /**
223
- * Gets the Supabase URL.
224
- * @returns The Supabase URL.
225
- * @deprecated All endpoints should use the backend URL instead.
226
- */
227
- getSupabaseUrl() {
228
- if (!this.rimoriInfo) {
229
- throw new Error('Supabase info not found');
230
- }
231
- return this.rimoriInfo.url;
232
- }
233
- getBackendUrl() {
234
- if (!this.rimoriInfo) {
235
- throw new Error('Rimori info not found');
236
- }
237
- return this.rimoriInfo.backendUrl;
238
- }
239
- getGlobalEventTopic(preliminaryTopic) {
240
- var _a, _b;
241
- if (preliminaryTopic.startsWith('global.')) {
242
- return preliminaryTopic;
243
- }
244
- if (preliminaryTopic.startsWith('self.')) {
245
- return preliminaryTopic;
246
- }
247
- const topicParts = preliminaryTopic.split('.');
248
- if (topicParts.length === 3) {
249
- if (!topicParts[0].startsWith('pl') && topicParts[0] !== 'global') {
250
- throw new Error("The event topic must start with the plugin id or 'global'.");
251
- }
252
- return preliminaryTopic;
253
- }
254
- else if (topicParts.length > 3) {
255
- throw new Error(`The event topic must consist of 3 parts. <pluginId>.<topic area>.<action>. Received: ${preliminaryTopic}`);
256
- }
257
- const topicRoot = (_b = (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b : 'global';
258
- return `${topicRoot}.${preliminaryTopic}`;
259
- }
260
208
  /**
261
209
  * Handles updates to RimoriInfo from rimori-main.
262
210
  * Updates the cached info and Supabase client, then notifies all registered callbacks.
@@ -265,9 +213,7 @@ export class RimoriCommunicationHandler {
265
213
  // Update cached rimoriInfo
266
214
  this.rimoriInfo = newInfo;
267
215
  // Update Supabase client with new token
268
- this.supabase = createClient(newInfo.url, newInfo.key, {
269
- accessToken: () => Promise.resolve(newInfo.token),
270
- });
216
+ this.supabase = this.getSupabase(newInfo.url, newInfo.key, newInfo.token);
271
217
  // Notify all registered callbacks
272
218
  this.updateCallbacks.forEach((callback) => {
273
219
  try {
@@ -1,204 +1,31 @@
1
- import { PostgrestQueryBuilder } from '@supabase/postgrest-js';
2
- import { GenericSchema } from '@supabase/supabase-js/dist/module/lib/types';
3
- import { Message, OnLLMResponse } from '../controller/AIController';
4
- import { ObjectRequest } from '../controller/ObjectController';
5
- import { UserInfo } from '../controller/SettingsController';
6
1
  import { SharedContent, SharedContentFilter, SharedContentObjectRequest } from '../controller/SharedContentController';
7
- import { CreateExerciseParams } from '../controller/ExerciseController';
8
- import { EventBusMessage, EventHandler, EventPayload, EventListener } from '../fromRimori/EventBus';
9
- import { ActivePlugin, MainPanelAction, Plugin, Tool } from '../fromRimori/PluginTypes';
10
- import { AccomplishmentPayload } from '../controller/AccomplishmentController';
11
- import { RimoriInfo } from './CommunicationHandler';
12
- import { Translator } from '../controller/TranslationController';
2
+ import { PluginModule } from './module/PluginModule';
3
+ import { DbModule } from './module/DbModule';
4
+ import { EventModule } from './module/EventModule';
5
+ import { AIModule } from './module/AIModule';
6
+ import { ExerciseModule } from './module/ExerciseModule';
13
7
  export declare class RimoriClient {
14
8
  private static instance;
15
- private superbase;
16
9
  private pluginController;
17
- private settingsController;
18
10
  private sharedContentController;
19
- private exerciseController;
20
- private accomplishmentHandler;
11
+ db: DbModule;
12
+ event: EventModule;
13
+ plugin: PluginModule;
14
+ ai: AIModule;
15
+ exercise: ExerciseModule;
21
16
  private rimoriInfo;
22
- private translator;
23
17
  private constructor();
24
- get plugin(): {
25
- pluginId: string;
26
- /**
27
- * The release channel of this plugin installation.
28
- * Determines which database schema is used for plugin tables.
29
- */
30
- releaseChannel: "alpha" | "beta" | "stable";
31
- /**
32
- * Set the settings for the plugin.
33
- * @param settings The settings to set.
34
- */
35
- setSettings: (settings: any) => Promise<void>;
36
- /**
37
- * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
38
- * @param defaultSettings The default settings to use if no settings are found.
39
- * @param genericSettings The type of settings to get.
40
- * @returns The settings for the plugin.
41
- */
42
- getSettings: <T extends object>(defaultSettings: T) => Promise<T>;
43
- /**
44
- * Get the current user info.
45
- * Note: For reactive updates in React components, use the userInfo from useRimori() hook instead.
46
- * @returns The user info.
47
- */
48
- getUserInfo: () => UserInfo;
49
- /**
50
- * Register a callback to be notified when RimoriInfo is updated.
51
- * This is useful for reacting to changes in user info, tokens, or other rimori data.
52
- * @param callback - Function to call with the new RimoriInfo
53
- * @returns Cleanup function to unregister the callback
54
- */
55
- onRimoriInfoUpdate: (callback: (info: RimoriInfo) => void) => (() => void);
56
- /**
57
- * Retrieves information about plugins, including:
58
- * - All installed plugins
59
- * - The currently active plugin in the main panel
60
- * - The currently active plugin in the side panel
61
- */
62
- getPluginInfo: () => {
63
- /**
64
- * All installed plugins.
65
- */
66
- installedPlugins: Plugin[];
67
- /**
68
- * The plugin that is loaded in the main panel.
69
- */
70
- mainPanelPlugin?: ActivePlugin;
71
- /**
72
- * The plugin that is loaded in the side panel.
73
- */
74
- sidePanelPlugin?: ActivePlugin;
75
- };
76
- /**
77
- * Get the translator for the plugin.
78
- * @returns The translator for the plugin.
79
- */
80
- getTranslator: () => Promise<Translator>;
81
- };
82
- get db(): {
83
- from: <ViewName extends string & keyof GenericSchema["Views"], View extends GenericSchema["Views"][ViewName]>(relation: string) => PostgrestQueryBuilder<GenericSchema, View, ViewName>;
84
- /**
85
- * The table prefix for of database tables of the plugin.
86
- */
87
- tablePrefix: string;
88
- /**
89
- * The database schema used for plugin tables.
90
- * Determined by rimori-main based on release channel:
91
- * - 'plugins_alpha' for alpha release channel
92
- * - 'plugins' for beta and stable release channels
93
- */
94
- schema: "plugins" | "plugins_alpha";
95
- /**
96
- * Get the table name for a given plugin table.
97
- * Internally all tables are prefixed with the plugin id. This function is used to get the correct table name for a given public table.
98
- * @param table The plugin table name to get the full table name for.
99
- * @returns The full table name.
100
- */
101
- getTableName: (table: string) => string;
102
- };
103
- event: {
104
- /**
105
- * Emit an event to Rimori or a plugin.
106
- * The topic schema is:
107
- * {pluginId}.{eventId}
108
- * Check out the event bus documentation for more information.
109
- * For triggering events from Rimori like context menu actions use the "global" keyword.
110
- * @param topic The topic to emit the event on.
111
- * @param data The data to emit.
112
- * @param eventId The event id.
113
- */
114
- emit: (topic: string, data?: any, eventId?: number) => void;
115
- /**
116
- * Request an event.
117
- * @param topic The topic to request the event on.
118
- * @param data The data to request.
119
- * @returns The response from the event.
120
- */
121
- request: <T>(topic: string, data?: any) => Promise<EventBusMessage<T>>;
122
- /**
123
- * Subscribe to an event.
124
- * @param topic The topic to subscribe to.
125
- * @param callback The callback to call when the event is emitted.
126
- * @returns An EventListener object containing an off() method to unsubscribe the listeners.
127
- */
128
- on: <T = EventPayload>(topic: string | string[], callback: EventHandler<T>) => EventListener;
129
- /**
130
- * Subscribe to an event once.
131
- * @param topic The topic to subscribe to.
132
- * @param callback The callback to call when the event is emitted.
133
- */
134
- once: <T = EventPayload>(topic: string, callback: EventHandler<T>) => void;
135
- /**
136
- * Respond to an event.
137
- * @param topic The topic to respond to.
138
- * @param data The data to respond with.
139
- */
140
- respond: <T = EventPayload>(topic: string | string[], data: EventPayload | ((data: EventBusMessage<T>) => EventPayload | Promise<EventPayload>)) => void;
141
- /**
142
- * Emit an accomplishment.
143
- * @param payload The payload to emit.
144
- */
145
- emitAccomplishment: (payload: AccomplishmentPayload) => void;
146
- /**
147
- * Subscribe to an accomplishment.
148
- * @param accomplishmentTopic The topic to subscribe to.
149
- * @param callback The callback to call when the accomplishment is emitted.
150
- */
151
- onAccomplishment: (accomplishmentTopic: string, callback: (payload: EventBusMessage<AccomplishmentPayload>) => void) => void;
152
- /**
153
- * Trigger an action that opens the sidebar and triggers an action in the designated plugin.
154
- * @param pluginId The id of the plugin to trigger the action for.
155
- * @param actionKey The key of the action to trigger.
156
- * @param text Optional text to be used for the action like for example text that the translator would look up.
157
- */
158
- emitSidebarAction: (pluginId: string, actionKey: string, text?: string) => void;
159
- /**
160
- * Subscribe to main panel actions triggered by the user from the dashboard.
161
- * @param callback Handler function that receives the action data when a matching action is triggered.
162
- * @param actionsToListen Optional filter to listen only to specific action keys. If empty or not provided, all actions will trigger the callback.
163
- * @returns An EventListener object with an `off()` method for cleanup.
164
- *
165
- * @example
166
- * ```ts
167
- * const listener = client.event.onMainPanelAction((data) => {
168
- * console.log('Action received:', data.action_key);
169
- * }, ['startSession', 'pauseSession']);
170
- *
171
- * // Clean up when component unmounts to prevent events from firing
172
- * // when navigating away or returning to the page
173
- * useEffect(() => {
174
- * return () => listener.off();
175
- * }, []);
176
- * ```
177
- *
178
- * **Important:** Always call `listener.off()` when your component unmounts or when you no longer need to listen.
179
- * This prevents the event handler from firing when navigating away from or returning to the page, which could
180
- * cause unexpected behavior or duplicate event handling.
181
- */
182
- onMainPanelAction: (callback: (data: MainPanelAction) => void, actionsToListen?: string | string[]) => EventListener;
183
- onSidePanelAction: (callback: (data: MainPanelAction) => void, actionsToListen?: string | string[]) => EventListener;
184
- };
185
18
  navigation: {
186
19
  toDashboard: () => void;
187
20
  };
188
21
  /**
189
22
  * Get a query parameter value that was passed via MessageChannel
190
23
  * @param key The query parameter key
24
+ * @deprecated Use the plugin.applicationMode and plugin.theme properties instead
191
25
  * @returns The query parameter value or null if not found
192
26
  */
193
27
  getQueryParam(key: string): string | null;
194
28
  static getInstance(pluginId?: string): Promise<RimoriClient>;
195
- ai: {
196
- getText: (messages: Message[], tools?: Tool[]) => Promise<string>;
197
- getSteamedText: (messages: Message[], onMessage: OnLLMResponse, tools?: Tool[]) => Promise<void>;
198
- getVoice: (text: string, voice?: string, speed?: number, language?: string) => Promise<Blob>;
199
- getTextFromVoice: (file: Blob) => Promise<string>;
200
- getObject: <T = any>(request: ObjectRequest) => Promise<T>;
201
- };
202
29
  runtime: {
203
30
  fetchBackend: (url: string, options: RequestInit) => Promise<Response>;
204
31
  };
@@ -281,28 +108,4 @@ export declare class RimoriClient {
281
108
  remove: (id: string) => Promise<SharedContent<any>>;
282
109
  };
283
110
  };
284
- exercise: {
285
- /**
286
- * Fetches weekly exercises from the weekly_exercises view.
287
- * Shows exercises for the current week that haven't expired.
288
- * @returns Array of exercise objects.
289
- */
290
- view: () => Promise<import("../controller/ExerciseController").Exercise[]>;
291
- /**
292
- * Creates a new exercise or multiple exercises via the backend API.
293
- * When creating multiple exercises, all requests are made in parallel but only one event is emitted.
294
- * @param params Exercise creation parameters (single or array).
295
- * @returns Created exercise objects.
296
- */
297
- add: (params: CreateExerciseParams | CreateExerciseParams[]) => Promise<import("../controller/ExerciseController").Exercise[]>;
298
- /**
299
- * Deletes an exercise via the backend API.
300
- * @param id The exercise ID to delete.
301
- * @returns Success status.
302
- */
303
- delete: (id: string) => Promise<{
304
- success: boolean;
305
- message: string;
306
- }>;
307
- };
308
111
  }