@rimori/client 1.3.0 → 1.4.0
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/.prettierignore +35 -0
- package/dist/cli/scripts/release/release-file-upload.js +1 -1
- package/dist/cli/types/DatabaseTypes.d.ts +2 -2
- package/dist/components/ai/Avatar.js +4 -2
- package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +1 -1
- package/dist/core/controller/AIController.js +9 -7
- package/dist/core/controller/ExerciseController.d.ts +52 -0
- package/dist/core/controller/ExerciseController.js +73 -0
- package/dist/core/core.d.ts +1 -0
- package/dist/plugin/Logger.d.ts +5 -0
- package/dist/plugin/Logger.js +56 -6
- package/dist/plugin/RimoriClient.d.ts +28 -2
- package/dist/plugin/RimoriClient.js +30 -1
- package/eslint.config.js +53 -0
- package/package.json +9 -2
- package/prettier.config.js +8 -0
- package/src/cli/scripts/release/release-file-upload.ts +1 -1
- package/src/cli/types/DatabaseTypes.ts +17 -10
- package/src/components/ai/Avatar.tsx +3 -2
- package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +176 -176
- package/src/core/controller/AIController.ts +36 -34
- package/src/core/controller/ExerciseController.ts +105 -0
- package/src/core/core.ts +1 -0
- package/src/plugin/Logger.ts +59 -8
- package/src/plugin/RimoriClient.ts +40 -6
- package/dist/components/LoggerExample.d.ts +0 -6
- package/dist/components/LoggerExample.js +0 -79
- package/dist/core/controller/AudioController.d.ts +0 -0
- package/dist/core/controller/AudioController.js +0 -1
- package/dist/hooks/UseLogger.d.ts +0 -30
- package/dist/hooks/UseLogger.js +0 -122
- package/dist/plugin/LoggerExample.d.ts +0 -16
- package/dist/plugin/LoggerExample.js +0 -140
- package/dist/utils/audioFormats.d.ts +0 -26
- package/dist/utils/audioFormats.js +0 -67
package/.prettierignore
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
yarn.lock
|
|
4
|
+
package-lock.json
|
|
5
|
+
bun.lockb
|
|
6
|
+
|
|
7
|
+
# Build outputs
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.tsbuildinfo
|
|
11
|
+
|
|
12
|
+
# Generated files
|
|
13
|
+
*.d.ts
|
|
14
|
+
*.js.map
|
|
15
|
+
|
|
16
|
+
# IDE files
|
|
17
|
+
.vscode/
|
|
18
|
+
.idea/
|
|
19
|
+
|
|
20
|
+
# OS files
|
|
21
|
+
.DS_Store
|
|
22
|
+
Thumbs.db
|
|
23
|
+
|
|
24
|
+
# Logs
|
|
25
|
+
*.log
|
|
26
|
+
npm-debug.log*
|
|
27
|
+
yarn-debug.log*
|
|
28
|
+
yarn-error.log*
|
|
29
|
+
|
|
30
|
+
# Coverage
|
|
31
|
+
coverage/
|
|
32
|
+
|
|
33
|
+
# Temporary files
|
|
34
|
+
*.tmp
|
|
35
|
+
*.temp
|
|
@@ -50,7 +50,7 @@ export function uploadDirectory(config, release_id) {
|
|
|
50
50
|
// Add to path mapping using ID as key
|
|
51
51
|
pathMapping[fileId] = relativePath;
|
|
52
52
|
// Create a Blob with the file content and content type
|
|
53
|
-
const blob = new Blob([fileContent], { type: contentType });
|
|
53
|
+
const blob = new Blob([new Uint8Array(fileContent)], { type: contentType });
|
|
54
54
|
// Add file to FormData with ID_filename format
|
|
55
55
|
const fileName = `${fileId}_${path.basename(filePath)}`;
|
|
56
56
|
formData.append('files', blob, fileName);
|
|
@@ -38,7 +38,7 @@ export interface DbColumnDefinition {
|
|
|
38
38
|
/** Whether the column is a primary key */
|
|
39
39
|
/** Restrictions for the column. If the column is restricted, the permission is further restricted. E.g. if the column is restricted to user, then the user can only read the column if they have the right permission.
|
|
40
40
|
* Example: Denying users to update the column, but allowing the moderator to update the column.
|
|
41
|
-
|
|
41
|
+
*/
|
|
42
42
|
restrict?: {
|
|
43
43
|
/** Restrictions for the user */
|
|
44
44
|
user: Partial<Omit<DbPermissionDefinition, 'delete'>>;
|
|
@@ -85,7 +85,7 @@ export interface DbTableDefinition {
|
|
|
85
85
|
*
|
|
86
86
|
* Defines the permissions for a database table.
|
|
87
87
|
*/
|
|
88
|
-
export type DbPermission =
|
|
88
|
+
export type DbPermission = 'NONE' | 'OWN' | 'ALL';
|
|
89
89
|
/**
|
|
90
90
|
* Permission definition for a database table.
|
|
91
91
|
* Defines the permissions for a database table.
|
|
@@ -20,6 +20,8 @@ export function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversat
|
|
|
20
20
|
setIsProcessingMessage(false);
|
|
21
21
|
}, [isLoading]);
|
|
22
22
|
useEffect(() => {
|
|
23
|
+
if (!voiceId)
|
|
24
|
+
return; //at the beginning when being mounted the voiceId is undefined
|
|
23
25
|
sender.setOnLoudnessChange((value) => event.emit('self.avatar.triggerLoudness', { loudness: value }));
|
|
24
26
|
sender.setOnEndOfSpeech(() => setAgentReplying(false));
|
|
25
27
|
if (!autoStartConversation)
|
|
@@ -33,12 +35,12 @@ export function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversat
|
|
|
33
35
|
else if (autoStartConversation.userMessage) {
|
|
34
36
|
append([{ role: 'user', content: autoStartConversation.userMessage, id: messages.length.toString() }]);
|
|
35
37
|
}
|
|
36
|
-
}, [autoStartConversation]);
|
|
38
|
+
}, [autoStartConversation, voiceId]);
|
|
37
39
|
useEffect(() => {
|
|
38
40
|
if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant') {
|
|
39
41
|
sender.handleNewText(lastMessage.content, isLoading);
|
|
40
42
|
if (lastMessage.toolCalls) {
|
|
41
|
-
console.log("unlocking mic", lastMessage)
|
|
43
|
+
// console.log("unlocking mic", lastMessage)
|
|
42
44
|
setAgentReplying(false);
|
|
43
45
|
setIsProcessingMessage(false);
|
|
44
46
|
}
|
|
@@ -90,16 +90,16 @@ export function streamChatGPT(backendUrl, messages, tools, onResponse, token) {
|
|
|
90
90
|
const data = JSON.parse(dataStr);
|
|
91
91
|
// Log the first message to understand the format
|
|
92
92
|
if (!content && !isToolCallMode) {
|
|
93
|
-
console.log('First stream message received:', data);
|
|
93
|
+
// console.log('First stream message received:', data);
|
|
94
94
|
}
|
|
95
95
|
switch (data.type) {
|
|
96
96
|
case 'start':
|
|
97
97
|
// Stream started, no action needed
|
|
98
|
-
console.log('Stream started');
|
|
98
|
+
// console.log('Stream started');
|
|
99
99
|
break;
|
|
100
100
|
case 'start-step':
|
|
101
101
|
// Step started, no action needed
|
|
102
|
-
console.log('Step started');
|
|
102
|
+
// console.log('Step started');
|
|
103
103
|
break;
|
|
104
104
|
case 'reasoning-start':
|
|
105
105
|
// Reasoning started, no action needed
|
|
@@ -127,26 +127,28 @@ export function streamChatGPT(backendUrl, messages, tools, onResponse, token) {
|
|
|
127
127
|
break;
|
|
128
128
|
case 'finish-step':
|
|
129
129
|
// Step finished, no action needed
|
|
130
|
-
console.log('Step finished');
|
|
130
|
+
// console.log('Step finished');
|
|
131
131
|
break;
|
|
132
132
|
case 'finish':
|
|
133
133
|
// Stream finished
|
|
134
|
-
console.log('Stream finished');
|
|
134
|
+
// console.log('Stream finished');
|
|
135
135
|
done = true;
|
|
136
136
|
break;
|
|
137
137
|
// Additional message types that might be present in the AI library
|
|
138
138
|
case 'tool-call':
|
|
139
|
+
case 'tool-input-available': //for now input calls should be handled the same way as tool calls
|
|
139
140
|
// Tool call initiated
|
|
140
141
|
console.log('Tool call initiated:', data);
|
|
141
142
|
isToolCallMode = true;
|
|
142
|
-
if (data.toolCallId && data.toolName && data.args) {
|
|
143
|
+
if (data.toolCallId && data.toolName && (data.args || data.input)) {
|
|
143
144
|
toolInvocations.push({
|
|
144
145
|
toolCallId: data.toolCallId,
|
|
145
146
|
toolName: data.toolName,
|
|
146
|
-
args: data.args
|
|
147
|
+
args: data.args || data.input
|
|
147
148
|
});
|
|
148
149
|
}
|
|
149
150
|
break;
|
|
151
|
+
case 'tool-input-delta': //for now input calls should be handled the same way as tool calls
|
|
150
152
|
case 'tool-call-delta':
|
|
151
153
|
// Tool call delta (for streaming tool calls)
|
|
152
154
|
console.log('Tool call delta:', data);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import { PluginController } from "../../plugin/PluginController";
|
|
3
|
+
export type TriggerAction = {
|
|
4
|
+
action_key: string;
|
|
5
|
+
} & Record<string, string | number | boolean>;
|
|
6
|
+
export interface CreateExerciseParams {
|
|
7
|
+
plugin_id: string;
|
|
8
|
+
start_date: string;
|
|
9
|
+
end_date: string;
|
|
10
|
+
trigger_action: TriggerAction;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
estimated_duration: number;
|
|
14
|
+
}
|
|
15
|
+
export interface Exercise {
|
|
16
|
+
id: string;
|
|
17
|
+
plugin_id: string;
|
|
18
|
+
start_date: string;
|
|
19
|
+
end_date: string;
|
|
20
|
+
trigger_action: TriggerAction;
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
estimated_duration: number;
|
|
24
|
+
created_at?: string;
|
|
25
|
+
updated_at?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class ExerciseController {
|
|
28
|
+
private supabase;
|
|
29
|
+
private pluginController;
|
|
30
|
+
constructor(supabase: SupabaseClient, pluginController: PluginController);
|
|
31
|
+
/**
|
|
32
|
+
* Fetches weekly exercises from the weekly_exercises view.
|
|
33
|
+
* Shows exercises for the current week that haven't expired.
|
|
34
|
+
* @returns Array of exercise objects.
|
|
35
|
+
*/
|
|
36
|
+
viewWeeklyExercises(): Promise<Exercise[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a new exercise via the backend API.
|
|
39
|
+
* @param params Exercise creation parameters.
|
|
40
|
+
* @returns Created exercise object.
|
|
41
|
+
*/
|
|
42
|
+
addExercise(params: CreateExerciseParams): Promise<Exercise>;
|
|
43
|
+
/**
|
|
44
|
+
* Deletes an exercise via the backend API.
|
|
45
|
+
* @param id The exercise ID to delete.
|
|
46
|
+
* @returns Success status.
|
|
47
|
+
*/
|
|
48
|
+
deleteExercise(id: string): Promise<{
|
|
49
|
+
success: boolean;
|
|
50
|
+
message: string;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export class ExerciseController {
|
|
11
|
+
constructor(supabase, pluginController) {
|
|
12
|
+
this.supabase = supabase;
|
|
13
|
+
this.pluginController = pluginController;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Fetches weekly exercises from the weekly_exercises view.
|
|
17
|
+
* Shows exercises for the current week that haven't expired.
|
|
18
|
+
* @returns Array of exercise objects.
|
|
19
|
+
*/
|
|
20
|
+
viewWeeklyExercises() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const { data, error } = yield this.supabase.from('weekly_exercises').select('*');
|
|
23
|
+
if (error) {
|
|
24
|
+
throw new Error(`Failed to fetch weekly exercises: ${error.message}`);
|
|
25
|
+
}
|
|
26
|
+
return data || [];
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new exercise via the backend API.
|
|
31
|
+
* @param params Exercise creation parameters.
|
|
32
|
+
* @returns Created exercise object.
|
|
33
|
+
*/
|
|
34
|
+
addExercise(params) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const token = yield this.pluginController.getToken();
|
|
37
|
+
const response = yield fetch(`${this.pluginController.getBackendUrl()}/exercises`, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: {
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
'Authorization': `Bearer ${token}`,
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify(params),
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
const errorText = yield response.text();
|
|
47
|
+
throw new Error(`Failed to create exercise: ${errorText}`);
|
|
48
|
+
}
|
|
49
|
+
return yield response.json();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Deletes an exercise via the backend API.
|
|
54
|
+
* @param id The exercise ID to delete.
|
|
55
|
+
* @returns Success status.
|
|
56
|
+
*/
|
|
57
|
+
deleteExercise(id) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const token = yield this.pluginController.getToken();
|
|
60
|
+
const response = yield fetch(`${this.pluginController.getBackendUrl()}/exercises/${id}`, {
|
|
61
|
+
method: 'DELETE',
|
|
62
|
+
headers: {
|
|
63
|
+
'Authorization': `Bearer ${token}`,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const errorText = yield response.text();
|
|
68
|
+
throw new Error(`Failed to delete exercise: ${errorText}`);
|
|
69
|
+
}
|
|
70
|
+
return yield response.json();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
package/dist/core/core.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from "../worker/WorkerSetup";
|
|
|
8
8
|
export { EventBusMessage } from "../fromRimori/EventBus";
|
|
9
9
|
export { Buddy, UserInfo } from "./controller/SettingsController";
|
|
10
10
|
export { SharedContent } from "./controller/SharedContentController";
|
|
11
|
+
export { Exercise, TriggerAction } from "./controller/ExerciseController";
|
|
11
12
|
export { Message, OnLLMResponse, ToolInvocation } from "./controller/AIController";
|
|
12
13
|
export { MacroAccomplishmentPayload, MicroAccomplishmentPayload } from "../plugin/AccomplishmentHandler";
|
|
13
14
|
export { Tool } from "../fromRimori/PluginTypes";
|
package/dist/plugin/Logger.d.ts
CHANGED
|
@@ -32,6 +32,11 @@ export declare class Logger {
|
|
|
32
32
|
* Override console methods globally to capture all console calls.
|
|
33
33
|
*/
|
|
34
34
|
private overrideConsoleMethods;
|
|
35
|
+
/**
|
|
36
|
+
* Get caller information from stack trace.
|
|
37
|
+
* @returns Object with location string and CSS style, or empty values for production
|
|
38
|
+
*/
|
|
39
|
+
private getCallerLocation;
|
|
35
40
|
/**
|
|
36
41
|
* Track mouse position for screenshot context.
|
|
37
42
|
*/
|
package/dist/plugin/Logger.js
CHANGED
|
@@ -115,30 +115,71 @@ export class Logger {
|
|
|
115
115
|
overrideConsoleMethods() {
|
|
116
116
|
// Override console.log
|
|
117
117
|
console.log = (...args) => {
|
|
118
|
-
this.
|
|
118
|
+
const { location, style } = this.getCallerLocation();
|
|
119
|
+
this.originalConsole.log(location, style, ...args);
|
|
119
120
|
this.handleConsoleCall('info', args);
|
|
120
121
|
};
|
|
121
122
|
// Override console.info
|
|
122
123
|
console.info = (...args) => {
|
|
123
|
-
this.
|
|
124
|
+
const { location, style } = this.getCallerLocation();
|
|
125
|
+
this.originalConsole.info(location, style, ...args);
|
|
124
126
|
this.handleConsoleCall('info', args);
|
|
125
127
|
};
|
|
126
128
|
// Override console.warn
|
|
127
129
|
console.warn = (...args) => {
|
|
128
|
-
this.
|
|
130
|
+
const { location, style } = this.getCallerLocation();
|
|
131
|
+
this.originalConsole.warn(location, style, ...args);
|
|
129
132
|
this.handleConsoleCall('warn', args);
|
|
130
133
|
};
|
|
131
134
|
// Override console.error
|
|
132
135
|
console.error = (...args) => {
|
|
133
|
-
this.
|
|
136
|
+
const { location, style } = this.getCallerLocation();
|
|
137
|
+
this.originalConsole.error(location, style, ...args);
|
|
134
138
|
this.handleConsoleCall('error', args);
|
|
135
139
|
};
|
|
136
140
|
// Override console.debug
|
|
137
141
|
console.debug = (...args) => {
|
|
138
|
-
this.
|
|
142
|
+
const { location, style } = this.getCallerLocation();
|
|
143
|
+
this.originalConsole.debug(location, style, ...args);
|
|
139
144
|
this.handleConsoleCall('debug', args);
|
|
140
145
|
};
|
|
141
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Get caller information from stack trace.
|
|
149
|
+
* @returns Object with location string and CSS style, or empty values for production
|
|
150
|
+
*/
|
|
151
|
+
getCallerLocation() {
|
|
152
|
+
const emptyResult = { location: "", style: "" };
|
|
153
|
+
const style = "color: #0063A2; font-weight: bold;";
|
|
154
|
+
if (this.isProduction)
|
|
155
|
+
return emptyResult;
|
|
156
|
+
try {
|
|
157
|
+
const stack = new Error().stack;
|
|
158
|
+
if (!stack)
|
|
159
|
+
return emptyResult;
|
|
160
|
+
const stackLines = stack.split('\n');
|
|
161
|
+
// Skip the first 3 lines: Error, getCallerLocation, overrideConsoleMethods wrapper
|
|
162
|
+
const callerLine = stackLines[3];
|
|
163
|
+
if (!callerLine)
|
|
164
|
+
return emptyResult;
|
|
165
|
+
// Extract file name and line number from stack trace
|
|
166
|
+
// Format: "at functionName (file:line:column)" or "at file:line:column"
|
|
167
|
+
const match = callerLine.match(/(?:at\s+.*?\s+\()?([^/\\(]+\.(?:ts|tsx|js|jsx)):(\d+):(\d+)\)?/);
|
|
168
|
+
if (match) {
|
|
169
|
+
const [, fileName, lineNumber] = match;
|
|
170
|
+
return { style, location: `%c[${fileName}:${lineNumber}]` };
|
|
171
|
+
}
|
|
172
|
+
// Fallback: try to extract just the file name
|
|
173
|
+
const simpleMatch = callerLine.match(/([^/\\]+\.(?:ts|tsx|js|jsx))/);
|
|
174
|
+
if (simpleMatch) {
|
|
175
|
+
return { style, location: `%c[${simpleMatch[1]}]` };
|
|
176
|
+
}
|
|
177
|
+
return emptyResult;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return emptyResult;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
142
183
|
/**
|
|
143
184
|
* Track mouse position for screenshot context.
|
|
144
185
|
*/
|
|
@@ -167,7 +208,16 @@ export class Logger {
|
|
|
167
208
|
return;
|
|
168
209
|
}
|
|
169
210
|
// Convert console arguments to message and data
|
|
170
|
-
const message = args.map(arg =>
|
|
211
|
+
const message = args.map(arg => {
|
|
212
|
+
if (typeof arg !== "object")
|
|
213
|
+
return arg;
|
|
214
|
+
try {
|
|
215
|
+
return JSON.stringify(arg);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
return "Error adding object to log: " + error.message + " " + String(arg);
|
|
219
|
+
}
|
|
220
|
+
}).join(' ');
|
|
171
221
|
const data = args.length > 1 ? args.slice(1) : undefined;
|
|
172
222
|
const entry = yield this.createLogEntry(level, message, data);
|
|
173
223
|
this.addLogEntry(entry);
|
|
@@ -4,14 +4,16 @@ import { Message, OnLLMResponse } from "../core/controller/AIController";
|
|
|
4
4
|
import { ObjectRequest } from "../core/controller/ObjectController";
|
|
5
5
|
import { UserInfo } from "../core/controller/SettingsController";
|
|
6
6
|
import { SharedContent, SharedContentFilter, SharedContentObjectRequest } from "../core/controller/SharedContentController";
|
|
7
|
+
import { CreateExerciseParams } from "../core/controller/ExerciseController";
|
|
7
8
|
import { EventBusMessage, EventHandler, EventPayload } from "../fromRimori/EventBus";
|
|
8
9
|
import { ActivePlugin, MainPanelAction, Plugin, Tool } from "../fromRimori/PluginTypes";
|
|
9
10
|
import { AccomplishmentPayload } from "./AccomplishmentHandler";
|
|
10
11
|
import { PluginController } from "./PluginController";
|
|
12
|
+
import { ClientServerOptions } from "@supabase/postgrest-js/dist/cjs/types/common/common";
|
|
11
13
|
interface Db {
|
|
12
14
|
from: {
|
|
13
|
-
<TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
|
|
14
|
-
<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
|
|
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>;
|
|
15
17
|
};
|
|
16
18
|
/**
|
|
17
19
|
* The table prefix for of database tables of the plugin.
|
|
@@ -63,6 +65,7 @@ export declare class RimoriClient {
|
|
|
63
65
|
private pluginController;
|
|
64
66
|
private settingsController;
|
|
65
67
|
private sharedContentController;
|
|
68
|
+
private exerciseController;
|
|
66
69
|
private accomplishmentHandler;
|
|
67
70
|
private rimoriInfo;
|
|
68
71
|
plugin: PluginInterface;
|
|
@@ -227,5 +230,28 @@ export declare class RimoriClient {
|
|
|
227
230
|
remove: (id: string) => Promise<SharedContent<any>>;
|
|
228
231
|
};
|
|
229
232
|
};
|
|
233
|
+
exercise: {
|
|
234
|
+
/**
|
|
235
|
+
* Fetches weekly exercises from the weekly_exercises view.
|
|
236
|
+
* Shows exercises for the current week that haven't expired.
|
|
237
|
+
* @returns Array of exercise objects.
|
|
238
|
+
*/
|
|
239
|
+
view: () => Promise<import("../core/controller/ExerciseController").Exercise[]>;
|
|
240
|
+
/**
|
|
241
|
+
* Creates a new exercise via the backend API.
|
|
242
|
+
* @param params Exercise creation parameters.
|
|
243
|
+
* @returns Created exercise object.
|
|
244
|
+
*/
|
|
245
|
+
add: (params: CreateExerciseParams) => Promise<import("../core/controller/ExerciseController").Exercise>;
|
|
246
|
+
/**
|
|
247
|
+
* Deletes an exercise via the backend API.
|
|
248
|
+
* @param id The exercise ID to delete.
|
|
249
|
+
* @returns Success status.
|
|
250
|
+
*/
|
|
251
|
+
delete: (id: string) => Promise<{
|
|
252
|
+
success: boolean;
|
|
253
|
+
message: string;
|
|
254
|
+
}>;
|
|
255
|
+
};
|
|
230
256
|
}
|
|
231
257
|
export {};
|
|
@@ -12,6 +12,7 @@ import { generateObject } from "../core/controller/ObjectController";
|
|
|
12
12
|
import { SettingsController } from "../core/controller/SettingsController";
|
|
13
13
|
import { SharedContentController } from "../core/controller/SharedContentController";
|
|
14
14
|
import { getSTTResponse, getTTSResponse } from "../core/controller/VoiceController";
|
|
15
|
+
import { ExerciseController } from "../core/controller/ExerciseController";
|
|
15
16
|
import { EventBus } from "../fromRimori/EventBus";
|
|
16
17
|
import { AccomplishmentHandler } from "./AccomplishmentHandler";
|
|
17
18
|
export class RimoriClient {
|
|
@@ -216,19 +217,47 @@ export class RimoriClient {
|
|
|
216
217
|
})
|
|
217
218
|
}
|
|
218
219
|
};
|
|
220
|
+
this.exercise = {
|
|
221
|
+
/**
|
|
222
|
+
* Fetches weekly exercises from the weekly_exercises view.
|
|
223
|
+
* Shows exercises for the current week that haven't expired.
|
|
224
|
+
* @returns Array of exercise objects.
|
|
225
|
+
*/
|
|
226
|
+
view: () => __awaiter(this, void 0, void 0, function* () {
|
|
227
|
+
return this.exerciseController.viewWeeklyExercises();
|
|
228
|
+
}),
|
|
229
|
+
/**
|
|
230
|
+
* Creates a new exercise via the backend API.
|
|
231
|
+
* @param params Exercise creation parameters.
|
|
232
|
+
* @returns Created exercise object.
|
|
233
|
+
*/
|
|
234
|
+
add: (params) => __awaiter(this, void 0, void 0, function* () {
|
|
235
|
+
return this.exerciseController.addExercise(params);
|
|
236
|
+
}),
|
|
237
|
+
/**
|
|
238
|
+
* Deletes an exercise via the backend API.
|
|
239
|
+
* @param id The exercise ID to delete.
|
|
240
|
+
* @returns Success status.
|
|
241
|
+
*/
|
|
242
|
+
delete: (id) => __awaiter(this, void 0, void 0, function* () {
|
|
243
|
+
return this.exerciseController.deleteExercise(id);
|
|
244
|
+
}),
|
|
245
|
+
};
|
|
219
246
|
this.rimoriInfo = info;
|
|
220
247
|
this.superbase = supabase;
|
|
221
248
|
this.pluginController = pluginController;
|
|
222
249
|
this.settingsController = new SettingsController(supabase, info.pluginId);
|
|
223
250
|
this.sharedContentController = new SharedContentController(this.superbase, this);
|
|
251
|
+
this.exerciseController = new ExerciseController(supabase, pluginController);
|
|
224
252
|
this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
|
|
225
253
|
this.from = this.from.bind(this);
|
|
254
|
+
this.getTableName = this.getTableName.bind(this);
|
|
226
255
|
this.db = {
|
|
227
256
|
from: this.from,
|
|
228
257
|
// storage: this.superbase.storage,
|
|
229
258
|
// functions: this.superbase.functions,
|
|
230
259
|
tablePrefix: info.tablePrefix,
|
|
231
|
-
getTableName: this.getTableName
|
|
260
|
+
getTableName: this.getTableName,
|
|
232
261
|
};
|
|
233
262
|
this.plugin = {
|
|
234
263
|
pluginId: info.pluginId,
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
5
|
+
import tseslint from 'typescript-eslint';
|
|
6
|
+
import prettier from 'eslint-plugin-prettier';
|
|
7
|
+
import prettierConfig from 'eslint-config-prettier';
|
|
8
|
+
|
|
9
|
+
export default [
|
|
10
|
+
{ ignores: ['dist', 'node_modules', 'build', '*.js'] },
|
|
11
|
+
js.configs.recommended,
|
|
12
|
+
...tseslint.configs.recommended,
|
|
13
|
+
prettierConfig,
|
|
14
|
+
{
|
|
15
|
+
files: ['**/*.{ts,tsx,js,jsx}'],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
ecmaVersion: 2020,
|
|
18
|
+
globals: {
|
|
19
|
+
...globals.browser,
|
|
20
|
+
...globals.node,
|
|
21
|
+
...globals.jest,
|
|
22
|
+
},
|
|
23
|
+
sourceType: 'module',
|
|
24
|
+
parserOptions: {
|
|
25
|
+
projectService: true,
|
|
26
|
+
tsconfigRootDir: import.meta.dirname,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
plugins: {
|
|
30
|
+
'react-hooks': reactHooks,
|
|
31
|
+
'react-refresh': reactRefresh,
|
|
32
|
+
prettier: prettier,
|
|
33
|
+
},
|
|
34
|
+
rules: {
|
|
35
|
+
...reactHooks.configs.recommended.rules,
|
|
36
|
+
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
|
37
|
+
'@typescript-eslint/no-unused-vars': 'warn',
|
|
38
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
39
|
+
'@typescript-eslint/no-floating-promises': 'warn',
|
|
40
|
+
'@typescript-eslint/no-unsafe-argument': 'warn',
|
|
41
|
+
'@typescript-eslint/explicit-function-return-type': 'warn',
|
|
42
|
+
'@typescript-eslint/explicit-module-boundary-types': 'warn',
|
|
43
|
+
'@typescript-eslint/no-unsafe-assignment': 'warn',
|
|
44
|
+
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
|
45
|
+
'@typescript-eslint/no-unsafe-call': 'warn',
|
|
46
|
+
'@typescript-eslint/no-unsafe-return': 'warn',
|
|
47
|
+
'@typescript-eslint/no-inferrable-types': 'warn',
|
|
48
|
+
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
49
|
+
'@typescript-eslint/ban-ts-comment': 'warn',
|
|
50
|
+
'prettier/prettier': 'error',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rimori/client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"bin": {
|
|
@@ -45,6 +45,13 @@
|
|
|
45
45
|
"form-data": "^4.0.2",
|
|
46
46
|
"node-fetch": "^3.3.2",
|
|
47
47
|
"sass": "^1.82.0",
|
|
48
|
-
"typescript": "^5.7.2"
|
|
48
|
+
"typescript": "^5.7.2",
|
|
49
|
+
"@eslint/js": "^9.37.0",
|
|
50
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
51
|
+
"eslint-plugin-react-refresh": "^0.4.23",
|
|
52
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
53
|
+
"eslint-config-prettier": "^10.1.8",
|
|
54
|
+
"globals": "^16.4.0",
|
|
55
|
+
"typescript-eslint": "^8.46.0"
|
|
49
56
|
}
|
|
50
57
|
}
|
|
@@ -52,7 +52,7 @@ export async function uploadDirectory(config: Config, release_id: string): Promi
|
|
|
52
52
|
pathMapping[fileId] = relativePath;
|
|
53
53
|
|
|
54
54
|
// Create a Blob with the file content and content type
|
|
55
|
-
const blob = new Blob([fileContent], { type: contentType });
|
|
55
|
+
const blob = new Blob([new Uint8Array(fileContent)], { type: contentType });
|
|
56
56
|
|
|
57
57
|
// Add file to FormData with ID_filename format
|
|
58
58
|
const fileName = `${fileId}_${path.basename(filePath)}`;
|