@rimori/client 1.3.1 → 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.
Files changed (35) hide show
  1. package/.prettierignore +35 -0
  2. package/dist/cli/scripts/release/release-file-upload.js +1 -1
  3. package/dist/cli/types/DatabaseTypes.d.ts +2 -2
  4. package/dist/components/ai/Avatar.js +4 -2
  5. package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +1 -1
  6. package/dist/core/controller/AIController.js +9 -7
  7. package/dist/core/controller/ExerciseController.d.ts +52 -0
  8. package/dist/core/controller/ExerciseController.js +73 -0
  9. package/dist/core/core.d.ts +1 -0
  10. package/dist/plugin/Logger.d.ts +5 -0
  11. package/dist/plugin/Logger.js +56 -6
  12. package/dist/plugin/RimoriClient.d.ts +28 -2
  13. package/dist/plugin/RimoriClient.js +30 -1
  14. package/eslint.config.js +53 -0
  15. package/package.json +15 -8
  16. package/prettier.config.js +8 -0
  17. package/src/cli/scripts/release/release-file-upload.ts +1 -1
  18. package/src/cli/types/DatabaseTypes.ts +17 -10
  19. package/src/components/ai/Avatar.tsx +3 -2
  20. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +176 -176
  21. package/src/core/controller/AIController.ts +36 -34
  22. package/src/core/controller/ExerciseController.ts +105 -0
  23. package/src/core/core.ts +1 -0
  24. package/src/plugin/Logger.ts +59 -8
  25. package/src/plugin/RimoriClient.ts +40 -6
  26. package/dist/components/LoggerExample.d.ts +0 -6
  27. package/dist/components/LoggerExample.js +0 -79
  28. package/dist/core/controller/AudioController.d.ts +0 -0
  29. package/dist/core/controller/AudioController.js +0 -1
  30. package/dist/hooks/UseLogger.d.ts +0 -30
  31. package/dist/hooks/UseLogger.js +0 -122
  32. package/dist/plugin/LoggerExample.d.ts +0 -16
  33. package/dist/plugin/LoggerExample.js +0 -140
  34. package/dist/utils/audioFormats.d.ts +0 -26
  35. package/dist/utils/audioFormats.js +0 -67
@@ -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 = "NONE" | "OWN" | "ALL";
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
  }
@@ -89,7 +89,7 @@ export class ChunkedAudioPlayer {
89
89
  cancelAnimationFrame(this.handle);
90
90
  }
91
91
  playChunk(chunk) {
92
- console.log({ queue: this.chunkQueue });
92
+ // console.log({queue: this.chunkQueue})
93
93
  if (!chunk) {
94
94
  return Promise.resolve();
95
95
  }
@@ -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
+ }
@@ -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";
@@ -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
  */
@@ -115,30 +115,71 @@ export class Logger {
115
115
  overrideConsoleMethods() {
116
116
  // Override console.log
117
117
  console.log = (...args) => {
118
- this.originalConsole.log(...args);
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.originalConsole.info(...args);
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.originalConsole.warn(...args);
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.originalConsole.error(...args);
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.originalConsole.debug(...args);
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 => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
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.bind(this),
260
+ getTableName: this.getTableName,
232
261
  };
233
262
  this.plugin = {
234
263
  pluginId: info.pluginId,
@@ -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.1",
3
+ "version": "1.4.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "bin": {
@@ -32,19 +32,26 @@
32
32
  "react-dom": "^18.0.0"
33
33
  },
34
34
  "dependencies": {
35
- "@supabase/supabase-js": "2.49.4",
35
+ "@supabase/supabase-js": "^2.48.1",
36
36
  "@tiptap/react": "2.10.3",
37
37
  "@tiptap/starter-kit": "2.10.3",
38
- "dotenv": "16.5.0",
39
- "html2canvas": "1.4.1",
40
- "react-icons": "5.4.0",
41
- "react-markdown": "10.1.0",
42
- "tiptap-markdown": "0.8.10"
38
+ "html2canvas": "^1.4.1",
39
+ "react-icons": "^5.4.0",
40
+ "react-markdown": "^10.1.0",
41
+ "tiptap-markdown": "^0.8.10"
43
42
  },
44
43
  "devDependencies": {
44
+ "dotenv": "^16.5.0",
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
  }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ printWidth: 120,
3
+ singleQuote: true,
4
+ trailingComma: "all",
5
+ semi: true,
6
+ tabWidth: 2,
7
+ useTabs: false,
8
+ };
@@ -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)}`;