@rimori/client 2.4.0 → 2.5.0-next.1

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 (70) 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/cli/scripts/release/release.js +0 -0
  4. package/dist/controller/SettingsController.d.ts +1 -1
  5. package/dist/controller/SharedContentController.d.ts +1 -1
  6. package/dist/fromRimori/EventBus.js +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/plugin/CommunicationHandler.d.ts +13 -8
  9. package/dist/plugin/CommunicationHandler.js +44 -59
  10. package/dist/plugin/RimoriClient.d.ts +11 -195
  11. package/dist/plugin/RimoriClient.js +16 -298
  12. package/dist/plugin/StandaloneClient.d.ts +1 -1
  13. package/dist/plugin/StandaloneClient.js +3 -2
  14. package/dist/plugin/module/AIModule.d.ts +49 -0
  15. package/dist/plugin/module/AIModule.js +81 -0
  16. package/dist/plugin/module/DbModule.d.ts +30 -0
  17. package/dist/plugin/module/DbModule.js +51 -0
  18. package/dist/plugin/module/EventModule.d.ts +99 -0
  19. package/dist/plugin/module/EventModule.js +162 -0
  20. package/dist/{controller/ExerciseController.d.ts → plugin/module/ExerciseModule.d.ts} +20 -16
  21. package/dist/{controller/ExerciseController.js → plugin/module/ExerciseModule.js} +27 -20
  22. package/dist/plugin/module/PluginModule.d.ts +76 -0
  23. package/dist/plugin/module/PluginModule.js +88 -0
  24. package/package.json +8 -3
  25. package/.github/workflows/pre-release.yml +0 -126
  26. package/.prettierignore +0 -35
  27. package/eslint.config.js +0 -53
  28. package/example/docs/devdocs.md +0 -241
  29. package/example/docs/overview.md +0 -29
  30. package/example/docs/userdocs.md +0 -126
  31. package/example/rimori.config.ts +0 -91
  32. package/example/worker/vite.config.ts +0 -26
  33. package/example/worker/worker.ts +0 -11
  34. package/prettier.config.js +0 -8
  35. package/src/cli/scripts/init/dev-registration.ts +0 -189
  36. package/src/cli/scripts/init/env-setup.ts +0 -44
  37. package/src/cli/scripts/init/file-operations.ts +0 -58
  38. package/src/cli/scripts/init/html-cleaner.ts +0 -45
  39. package/src/cli/scripts/init/main.ts +0 -175
  40. package/src/cli/scripts/init/package-setup.ts +0 -113
  41. package/src/cli/scripts/init/router-transformer.ts +0 -332
  42. package/src/cli/scripts/init/tailwind-config.ts +0 -66
  43. package/src/cli/scripts/init/vite-config.ts +0 -73
  44. package/src/cli/scripts/release/detect-translation-languages.ts +0 -37
  45. package/src/cli/scripts/release/release-config-upload.ts +0 -119
  46. package/src/cli/scripts/release/release-db-update.ts +0 -97
  47. package/src/cli/scripts/release/release-file-upload.ts +0 -138
  48. package/src/cli/scripts/release/release.ts +0 -85
  49. package/src/cli/types/DatabaseTypes.ts +0 -125
  50. package/src/controller/AIController.ts +0 -295
  51. package/src/controller/AccomplishmentController.ts +0 -188
  52. package/src/controller/AudioController.ts +0 -64
  53. package/src/controller/ExerciseController.ts +0 -117
  54. package/src/controller/ObjectController.ts +0 -120
  55. package/src/controller/SettingsController.ts +0 -186
  56. package/src/controller/SharedContentController.ts +0 -365
  57. package/src/controller/TranslationController.ts +0 -136
  58. package/src/controller/VoiceController.ts +0 -33
  59. package/src/fromRimori/EventBus.ts +0 -382
  60. package/src/fromRimori/PluginTypes.ts +0 -214
  61. package/src/fromRimori/readme.md +0 -2
  62. package/src/index.ts +0 -19
  63. package/src/plugin/CommunicationHandler.ts +0 -310
  64. package/src/plugin/Logger.ts +0 -394
  65. package/src/plugin/RimoriClient.ts +0 -530
  66. package/src/plugin/StandaloneClient.ts +0 -125
  67. package/src/utils/difficultyConverter.ts +0 -15
  68. package/src/utils/endpoint.ts +0 -3
  69. package/src/worker/WorkerSetup.ts +0 -35
  70. package/tsconfig.json +0 -17
@@ -1,91 +0,0 @@
1
- import { RimoriPluginConfig } from '@rimori/client';
2
-
3
- /**
4
- * This is an example of a Rimori plugin configuration file. It is based on the Rimori Flashcards plugin.
5
- * It is used to configure the plugin and its pages, sidebar, settings, context menu actions, documentation, and worker.
6
- */
7
-
8
- const config: RimoriPluginConfig = {
9
- id: 'pl1234567890', // This is the plugin id. You can find it in the plugin's package.json file.
10
- info: {
11
- title: 'Flashcards',
12
- description:
13
- "The Rimori Flashcards Plugin is a powerful tool for learning and memorization using spaced repetition. It helps you efficiently review information, whether you're learning a language, preparing for exams, or mastering new skills. The plugin uses advanced algorithms to schedule your reviews at optimal intervals, maximizing retention while minimizing study time.",
14
- logo: 'logo.png',
15
- website: 'https://rimori.se',
16
- },
17
- pages: {
18
- main: [
19
- {
20
- id: '1',
21
- url: '#/',
22
- show: true,
23
- name: 'Flashcards',
24
- root: 'vocabulary',
25
- description: 'Quickly memorizing info by using flashcards.',
26
- },
27
- {
28
- // This is a page that is not shown in the navbar. It is used to trigger the flashcards action.
29
- id: '2',
30
- url: '#/deck/custom',
31
- show: false,
32
- root: 'vocabulary',
33
- name: 'Latest flashcard deck training',
34
- description: 'Training the latest flashcards.',
35
- action: {
36
- key: 'flashcards',
37
- parameters: {
38
- total_amount: {
39
- type: 'number',
40
- description: 'Number of flashcards to practice. Default is 70 (10 new + 20 reviewed + 40 forgotten).',
41
- },
42
- deck: {
43
- type: 'string',
44
- enum: ['latest', 'random', 'oldest', 'mix', 'best_known'],
45
- description: 'Type of deck to practice from',
46
- },
47
- },
48
- },
49
- },
50
- ],
51
- sidebar: [
52
- {
53
- id: 'translate',
54
- url: '#/sidebar/translate',
55
- name: 'Translate',
56
- icon: 'translate.png',
57
- description: 'Translate words.',
58
- },
59
- {
60
- id: 'flashcard_quick_add',
61
- url: '#/sidebar/add',
62
- name: 'Quick add',
63
- icon: 'logo.png',
64
- description: 'Quickly add a word to your flashcards.',
65
- },
66
- ],
67
- settings: '/settings',
68
- },
69
- context_menu_actions: [
70
- {
71
- text: 'Translate',
72
- plugin_id: 'pl1234567890',
73
- action_key: 'translate',
74
- },
75
- {
76
- text: 'Quick add',
77
- plugin_id: 'pl1234567890',
78
- action_key: 'flashcard_quick_add',
79
- },
80
- ],
81
- documentation: {
82
- overview_path: 'docs/overview.md',
83
- user_path: 'docs/userdocs.md',
84
- developer_path: 'docs/devdocs.md',
85
- },
86
- worker: {
87
- url: 'web-worker.js',
88
- },
89
- };
90
-
91
- export default config;
@@ -1,26 +0,0 @@
1
- import { defineConfig } from 'vite';
2
- import path from 'path';
3
-
4
- export default defineConfig({
5
- root: __dirname,
6
- build: {
7
- minify: process.env.VITE_MINIFY === 'true',
8
- lib: {
9
- entry: 'worker.ts',
10
- formats: ['iife'],
11
- name: 'PluginFooWorker',
12
- fileName: () => 'web-worker.js', // used in rollupOptions.entryFileNames
13
- },
14
- outDir: path.resolve(__dirname, '../public'),
15
- emptyOutDir: false,
16
- rollupOptions: {
17
- // Exclude DOM-only libraries that can't run in workers
18
- // html2canvas is provided by @rimori/react-client for browser contexts
19
- external: ['html2canvas'],
20
- output: {
21
- inlineDynamicImports: true,
22
- entryFileNames: 'web-worker.js',
23
- },
24
- },
25
- },
26
- });
@@ -1,11 +0,0 @@
1
- import { setupWorker, RimoriClient } from '@rimori/client/core';
2
-
3
- setupWorker(async (client: RimoriClient) => {
4
- console.log('[Worker] initialized');
5
-
6
- // listening to events for this plugin to create flashcards
7
- client.event.respond<{ front: string; back: string }>('flashcards.create', ({ data }) => {
8
- console.log('[Worker] creating flashcards in database', data);
9
- return { success: true };
10
- });
11
- });
@@ -1,8 +0,0 @@
1
- export default {
2
- printWidth: 120,
3
- singleQuote: true,
4
- trailingComma: "all",
5
- semi: true,
6
- tabWidth: 2,
7
- useTabs: false,
8
- };
@@ -1,189 +0,0 @@
1
- import { createClient } from '@supabase/supabase-js';
2
- import path from 'path';
3
- import * as readline from 'readline';
4
- import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from '../../../utils/endpoint.js';
5
-
6
- export interface UserCredentials {
7
- email: string;
8
- password: string;
9
- }
10
-
11
- export interface DeveloperRegisterResponse {
12
- plugin_id: string;
13
- access_token: string;
14
- }
15
-
16
- /**
17
- * Prompts user for email and password credentials.
18
- * @returns Promise resolving to user credentials.
19
- */
20
- export async function askForCredentials(): Promise<UserCredentials> {
21
- const rl = readline.createInterface({
22
- input: process.stdin,
23
- output: process.stdout,
24
- });
25
-
26
- return new Promise((resolve) => {
27
- rl.question('Enter your email: ', (email) => {
28
- rl.close();
29
-
30
- // Create a new interface for password input with muted output
31
- const passwordRl = readline.createInterface({
32
- input: process.stdin,
33
- output: process.stdout,
34
- terminal: false,
35
- });
36
-
37
- process.stdout.write('Enter your password: ');
38
-
39
- // Set up stdin for raw input
40
- process.stdin.setRawMode(true);
41
- process.stdin.resume();
42
-
43
- let password = '';
44
-
45
- const onData = (buffer: Buffer) => {
46
- const char = buffer.toString('utf8');
47
-
48
- if (char === '\r' || char === '\n') {
49
- // Enter pressed
50
- process.stdin.setRawMode(false);
51
- process.stdin.pause();
52
- process.stdin.removeListener('data', onData);
53
- process.stdout.write('\n');
54
- passwordRl.close();
55
- resolve({ email: email.trim(), password: password.trim() });
56
- } else if (char === '\u0003') {
57
- // Ctrl+C
58
- process.stdin.setRawMode(false);
59
- process.stdin.pause();
60
- process.stdin.removeListener('data', onData);
61
- process.stdout.write('\n');
62
- process.exit(0);
63
- } else if (char === '\u007f' || char === '\b') {
64
- // Backspace
65
- if (password.length > 0) {
66
- password = password.slice(0, -1);
67
- process.stdout.write('\b \b');
68
- }
69
- } else if (char.charCodeAt(0) >= 32 && char.charCodeAt(0) <= 126) {
70
- // Printable characters
71
- password += char;
72
- process.stdout.write('*');
73
- }
74
- };
75
-
76
- process.stdin.on('data', onData);
77
- });
78
- });
79
- }
80
-
81
- /**
82
- * Prompts user for development port with default value.
83
- * @returns Promise resolving to the selected port.
84
- */
85
- export async function askForPort(): Promise<number> {
86
- const rl = readline.createInterface({
87
- input: process.stdin,
88
- output: process.stdout,
89
- });
90
-
91
- return new Promise((resolve) => {
92
- rl.question('Enter development port (default: 3000): ', (answer) => {
93
- rl.close();
94
- const port = answer.trim() || '3000';
95
-
96
- // Validate port is a number
97
- const portNumber = parseInt(port, 10);
98
- if (isNaN(portNumber) || portNumber < 1 || portNumber > 65535) {
99
- console.error('Error: Port must be a valid number between 1 and 65535');
100
- process.exit(1);
101
- }
102
-
103
- resolve(portNumber);
104
- });
105
- });
106
- }
107
-
108
- /**
109
- * Authenticates with Supabase using email and password.
110
- * @param param
111
- * @param param.email - User email address.
112
- * @param param.password - User password.
113
- * @returns Promise resolving to JWT access token.
114
- * @throws {Error} if authentication fails.
115
- */
116
- export async function authenticateWithSupabase({ email, password }: UserCredentials): Promise<string> {
117
- console.log('🔐 Authenticating with Supabase...');
118
-
119
- // Initialize Supabase client (you may need to adjust the URL and key)
120
- const supabaseUrl = process.env.SUPABASE_URL || DEFAULT_ENDPOINT;
121
- const supabaseKey = process.env.SUPABASE_ANON_KEY || DEFAULT_ANON_KEY;
122
-
123
- const supabase = createClient(supabaseUrl, supabaseKey);
124
-
125
- try {
126
- const { data, error } = await supabase.auth.signInWithPassword({
127
- email,
128
- password,
129
- });
130
-
131
- if (error) {
132
- throw new Error(`Authentication failed: ${error.message}`);
133
- }
134
-
135
- if (!data.session?.access_token) {
136
- throw new Error('No access token received from authentication');
137
- }
138
-
139
- console.log('✅ Supabase authentication successful!');
140
- return data.session.access_token;
141
- } catch (error) {
142
- throw new Error(`Supabase authentication failed: ${error}`);
143
- }
144
- }
145
-
146
- /**
147
- * Registers developer and gets plugin credentials from the backend.
148
- * @param jwtToken - JWT token from Supabase authentication.
149
- * @param port - Development port for the plugin.
150
- * @returns Promise resolving to plugin ID and access token.
151
- * @throws {Error} if registration request fails.
152
- */
153
- export async function registerDeveloper(jwtToken: string, port: number): Promise<DeveloperRegisterResponse> {
154
- console.log('🚀 Registering developer and creating plugin...');
155
-
156
- try {
157
- const currentFolderName = path.basename(process.cwd());
158
- const body: any = { port, pluginName: currentFolderName };
159
- const backendUrl = process.env.RIMORI_BACKEND_URL || 'https://api.rimori.se';
160
-
161
- const response = await fetch(backendUrl + '/developer/register', {
162
- method: 'POST',
163
- headers: {
164
- 'Content-Type': 'application/json',
165
- Authorization: `Bearer ${jwtToken}`,
166
- },
167
- body: JSON.stringify(body),
168
- });
169
-
170
- if (!response.ok) {
171
- console.error(await response.text());
172
- throw new Error(`HTTP error! status: ${response.status}`);
173
- }
174
-
175
- const data: DeveloperRegisterResponse = await response.json();
176
-
177
- if (!data.plugin_id || !data.access_token) {
178
- throw new Error('Invalid response: missing pluginId or access_token');
179
- }
180
-
181
- console.log('✅ Plugin registration successful!');
182
- console.log(`Plugin ID: ${data.plugin_id}`);
183
-
184
- return data;
185
- } catch (error) {
186
- console.error(error);
187
- throw new Error(`Developer registration failed: ${error}`);
188
- }
189
- }
@@ -1,44 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
-
4
- /**
5
- * Creates or updates the .env file with the plugin token.
6
- * @param token - The plugin authentication token.
7
- */
8
- export function setupEnvFile(token: string): void {
9
- const envPath = path.resolve('.env');
10
- if (!fs.existsSync(envPath)) {
11
- const envContent = `RIMORI_TOKEN=${token}\n`;
12
- fs.writeFileSync(envPath, envContent, 'utf8');
13
- console.log('Created .env file with RIMORI_TOKEN');
14
- } else {
15
- console.log('.env file already exists, skipping creation');
16
- }
17
- }
18
-
19
- /**
20
- * Updates .gitignore to exclude .env files.
21
- */
22
- export function updateGitignore(): void {
23
- const gitignorePath = path.resolve('.gitignore');
24
- let gitignoreContent = '';
25
- let needsUpdate = false;
26
-
27
- if (fs.existsSync(gitignorePath)) {
28
- gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
29
- // Check if .env is already in .gitignore
30
- if (!gitignoreContent.includes('.env')) {
31
- needsUpdate = true;
32
- }
33
- } else {
34
- needsUpdate = true;
35
- }
36
-
37
- if (needsUpdate) {
38
- gitignoreContent += '\n.env\npublic/web-worker.js\n';
39
- fs.writeFileSync(gitignorePath, gitignoreContent, 'utf8');
40
- console.log('Added .env to .gitignore');
41
- } else {
42
- console.log('.env already in .gitignore, skipping update');
43
- }
44
- }
@@ -1,58 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import { dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
-
6
- // ES module equivalent of __dirname
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
-
10
- /**
11
- * Configuration mapping source files to destination files.
12
- * Key: Source path relative to __dirname
13
- * Value: Destination path relative to current working directory
14
- */
15
- const FILE_COPY_MAP: Record<string, string> = {
16
- '../../../../example/rimori.config.ts': './rimori/rimori.config.ts',
17
- '../../../../README.md': './rimori/readme.md',
18
- '../../../../example/docs/overview.md': './public/docs/overview.md',
19
- '../../../../example/docs/devdocs.md': './public/docs/devdocs.md',
20
- '../../../../example/docs/userdocs.md': './public/docs/userdocs.md',
21
- '../../../../example/worker/worker.ts': './worker/worker.ts',
22
- '../../../../example/worker/vite.config.ts': './worker/vite.config.ts',
23
- };
24
-
25
- /**
26
- * Copies necessary files and creates directories for the plugin setup.
27
- */
28
- export function copyPluginFiles(): void {
29
- console.log('Copying plugin files...');
30
-
31
- for (const [srcRelativePath, destRelativePath] of Object.entries(FILE_COPY_MAP)) {
32
- const srcPath = path.resolve(__dirname, srcRelativePath);
33
- const destPath = path.resolve(destRelativePath);
34
- const destDir = path.dirname(destPath);
35
-
36
- // Check if source file exists
37
- if (!fs.existsSync(srcPath)) {
38
- console.log(`Warning: Source file not found: ${srcPath}`);
39
- continue;
40
- }
41
-
42
- // Create destination directory if it doesn't exist
43
- if (!fs.existsSync(destDir)) {
44
- console.log(`Creating directory: ${destDir}`);
45
- fs.mkdirSync(destDir, { recursive: true });
46
- }
47
-
48
- // Only copy if destination file doesn't exist
49
- if (!fs.existsSync(destPath)) {
50
- fs.copyFileSync(srcPath, destPath);
51
- console.log(`Copied: ${srcRelativePath} -> ${destRelativePath}`);
52
- } else {
53
- console.log(`File already exists, skipping: ${destRelativePath}`);
54
- }
55
- }
56
-
57
- console.log('Plugin file copying completed.');
58
- }
@@ -1,45 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
-
4
- /**
5
- * Removes all meta tags from HTML content except viewport and charset.
6
- * @param htmlContent - The HTML content to process.
7
- * @returns The processed HTML content with unwanted meta tags removed.
8
- */
9
- function removeUnwantedMetaTags(htmlContent: string): string {
10
- // Remove all meta tags except those with name="viewport" or charset attribute
11
- let cleanedContent = htmlContent.replace(/<meta\s+(?![^>]*(?:name\s*=\s*["']viewport["']|charset\s*=))[^>]*>/gi, '');
12
-
13
- // Remove empty lines left behind
14
- cleanedContent = cleanedContent.replace(/^\s*[\r\n]/gm, '');
15
-
16
- return cleanedContent;
17
- }
18
-
19
- /**
20
- * Processes HTML files to remove unwanted meta tags.
21
- */
22
- export function cleanHtmlMetaTags(): void {
23
- const filePath = path.resolve('./index.html');
24
-
25
- if (!filePath.endsWith('.html')) {
26
- return;
27
- }
28
-
29
- if (!fs.existsSync(filePath)) {
30
- console.log(`Warning: HTML file not found: ${filePath}`);
31
- return;
32
- }
33
-
34
- try {
35
- const content = fs.readFileSync(filePath, 'utf8');
36
- const cleanedContent = removeUnwantedMetaTags(content);
37
-
38
- if (content !== cleanedContent) {
39
- fs.writeFileSync(filePath, cleanedContent, 'utf8');
40
- console.log(`Cleaned meta tags in: ${filePath}`);
41
- }
42
- } catch (error) {
43
- console.error(`Error processing HTML file ${filePath}:`, error);
44
- }
45
- }
@@ -1,175 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import * as fs from 'fs';
4
- import * as path from 'path';
5
- import { askForCredentials, askForPort, authenticateWithSupabase, registerDeveloper } from './dev-registration.js';
6
- import { setupEnvFile, updateGitignore } from './env-setup.js';
7
- import { copyPluginFiles } from './file-operations.js';
8
- import { cleanHtmlMetaTags } from './html-cleaner.js';
9
- import { updatePackageJson, type PackageJson } from './package-setup.js';
10
- import { transformAppRouter } from './router-transformer.js';
11
- import { updateTailwindConfig } from './tailwind-config.js';
12
- import { updateViteConfigBase } from './vite-config.js';
13
- import 'dotenv/config';
14
-
15
- /**
16
- * Main function that handles the complete plugin setup flow.
17
- */
18
- async function main(): Promise<void> {
19
- try {
20
- // Check for --upgrade flag
21
- const isUpgrade = process.argv.includes('--upgrade');
22
-
23
- if (isUpgrade) {
24
- console.log('🔄 Starting Rimori Plugin Upgrade...');
25
- } else {
26
- console.log('🎯 Starting Rimori Plugin Setup...');
27
- }
28
- console.log('');
29
-
30
- // Check if plugin is already initialized (skip for upgrade mode)
31
- if (!isUpgrade) {
32
- const packageJsonPath = path.resolve('./package.json');
33
- if (fs.existsSync(packageJsonPath)) {
34
- try {
35
- const packageJson: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
36
- if (packageJson.r_id) {
37
- console.log('❌ Plugin is already initialized!');
38
- console.log(`Plugin ID: ${packageJson.r_id}`);
39
- console.log('');
40
- console.log(
41
- 'If you want to reinitialize the plugin, please remove the "r_id" field from package.json first.',
42
- );
43
- console.log(
44
- 'Or use the --upgrade flag to upgrade the plugin configuration without changing the plugin ID.',
45
- );
46
- process.exit(0);
47
- }
48
- } catch (error) {
49
- console.warn('Warning: Could not read package.json, continuing with setup...');
50
- }
51
- }
52
- }
53
-
54
- let pluginId: string = '';
55
-
56
- if (isUpgrade) {
57
- // For upgrade mode, only ask for port and setup plugin
58
- console.log('🔄 Upgrade mode: Skipping authentication and plugin registration...');
59
- console.log('');
60
-
61
- // Get plugin ID from existing package.json
62
- try {
63
- const packageJsonPath = path.resolve('./package.json');
64
- const packageJson: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
65
- pluginId = packageJson.r_id || '';
66
- } catch (error) {
67
- console.warn('Warning: Could not read plugin ID from package.json');
68
- }
69
-
70
- // Ask for development port
71
- const port = await askForPort();
72
- console.log('');
73
-
74
- // Update package.json in upgrade mode
75
- updatePackageJson({
76
- port,
77
- isUpgrade: true,
78
- });
79
-
80
- // Copy files
81
- copyPluginFiles();
82
-
83
- // Update gitignore
84
- updateGitignore();
85
- } else {
86
- // Step 1: Get user credentials
87
- const credentials = await askForCredentials();
88
- console.log('');
89
-
90
- // Step 2: Authenticate with Supabase
91
- const jwtToken = await authenticateWithSupabase(credentials);
92
- console.log('');
93
-
94
- // Step 3: Ask for development port
95
- const port = await askForPort();
96
- console.log('');
97
-
98
- // Step 4: Register developer and get plugin credentials
99
- const { plugin_id, access_token } = await registerDeveloper(jwtToken, port);
100
- pluginId = plugin_id;
101
- console.log('');
102
-
103
- // Step 5: Update package.json
104
- updatePackageJson({
105
- pluginId: plugin_id,
106
- port,
107
- isUpgrade: false,
108
- });
109
-
110
- // Step 6: Setup environment file
111
- setupEnvFile(access_token);
112
-
113
- // Step 7: Copy necessary files
114
- copyPluginFiles();
115
-
116
- // Step 8: Update gitignore
117
- updateGitignore();
118
- }
119
-
120
- // Setup vite config base
121
- try {
122
- console.log('Updating vite config base...');
123
- updateViteConfigBase();
124
- console.log('✅ Vite config base updated');
125
- } catch (error) {
126
- console.warn(
127
- `Warning: Could not update vite.config.ts base property: ${error instanceof Error ? error.message : error}`,
128
- );
129
- }
130
-
131
- // Clean meta tags from index.html after vite adaptation
132
- cleanHtmlMetaTags();
133
- console.log('✅ Meta tags cleaned from index.html');
134
-
135
- // Update Tailwind CSS configuration
136
- updateTailwindConfig();
137
-
138
- // Transform App.tsx to use PluginProvider with HashRouter
139
- if (pluginId) {
140
- try {
141
- transformAppRouter(pluginId);
142
- } catch (error) {
143
- console.warn(`Warning: Could not transform App.tsx router: ${error instanceof Error ? error.message : error}`);
144
- }
145
- } else {
146
- console.warn('Warning: Plugin ID not available, skipping router transformation');
147
- }
148
-
149
- console.log('');
150
- console.log('✅ Plugin ' + (isUpgrade ? 'upgrade' : 'setup') + ' completed successfully!');
151
- console.log('');
152
- console.log('Next steps:');
153
- console.log('1. Check out ./rimori/readme.md for more information about how to make the most out of the plugin.');
154
- console.log('2. Adapt the ./rimori/rimori.config.ts file to your needs.');
155
- console.log(
156
- '3. Under ./public/docs/ you can find the documentation for an example flashcard plugin to get started easier.',
157
- );
158
- console.log('4. Start development with: yarn dev');
159
- console.log('');
160
- console.log(`The plugin should now be accessible at: http://localhost:${3000}`);
161
- console.log('');
162
- console.log(
163
- 'If you want to release the plugin, simply run: "yarn release:<alpha|beta|stable>" (details are available in ./rimori/readme.md)',
164
- );
165
- } catch (error) {
166
- console.error(`❌ Error: ${error instanceof Error ? error.message : error}`);
167
- console.error('');
168
- console.error('Make sure that:');
169
- console.error('1. Your Supabase credentials are correct');
170
- console.error('2. You have internet connection for authentication');
171
- process.exit(1);
172
- }
173
- }
174
-
175
- main();