@rimori/client 1.1.10 → 1.3.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/README.md +189 -63
- package/dist/cli/scripts/init/dev-registration.d.ts +35 -0
- package/dist/cli/scripts/init/dev-registration.js +174 -0
- package/dist/cli/scripts/init/env-setup.d.ts +9 -0
- package/dist/cli/scripts/init/env-setup.js +43 -0
- package/dist/cli/scripts/init/file-operations.d.ts +4 -0
- package/dist/cli/scripts/init/file-operations.js +51 -0
- package/dist/cli/scripts/init/html-cleaner.d.ts +4 -0
- package/dist/cli/scripts/init/html-cleaner.js +38 -0
- package/dist/cli/scripts/init/main.d.ts +2 -0
- package/dist/cli/scripts/init/main.js +160 -0
- package/dist/cli/scripts/init/package-setup.d.ts +32 -0
- package/dist/cli/scripts/init/package-setup.js +75 -0
- package/dist/cli/scripts/init/router-transformer.d.ts +6 -0
- package/dist/cli/scripts/init/router-transformer.js +254 -0
- package/dist/cli/scripts/init/tailwind-config.d.ts +4 -0
- package/dist/cli/scripts/init/tailwind-config.js +56 -0
- package/dist/cli/scripts/init/vite-config.d.ts +20 -0
- package/dist/cli/scripts/init/vite-config.js +54 -0
- package/dist/cli/scripts/release/release-config-upload.d.ts +7 -0
- package/dist/cli/scripts/release/release-config-upload.js +116 -0
- package/dist/cli/scripts/release/release-db-update.d.ts +6 -0
- package/dist/cli/scripts/release/release-db-update.js +100 -0
- package/dist/cli/scripts/release/release-file-upload.d.ts +6 -0
- package/dist/cli/scripts/release/release-file-upload.js +136 -0
- package/dist/cli/scripts/release/release.d.ts +23 -0
- package/dist/cli/scripts/release/release.js +70 -0
- package/dist/cli/types/DatabaseTypes.d.ts +103 -0
- package/dist/cli/types/DatabaseTypes.js +2 -0
- package/dist/components/LoggerExample.d.ts +6 -0
- package/dist/components/LoggerExample.js +79 -0
- package/dist/components/ai/Assistant.js +5 -5
- package/dist/components/ai/Avatar.d.ts +3 -2
- package/dist/components/ai/Avatar.js +11 -6
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -1
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +1 -0
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +48 -33
- package/dist/components/ai/utils.js +0 -1
- package/dist/components/audio/Playbutton.js +4 -4
- package/dist/{core → components}/components/ContextMenu.js +50 -11
- package/dist/components.d.ts +5 -5
- package/dist/components.js +5 -5
- package/dist/core/controller/AIController.d.ts +15 -0
- package/dist/core/controller/AIController.js +253 -0
- package/dist/core/controller/AudioController.d.ts +0 -0
- package/dist/core/controller/AudioController.js +1 -0
- package/dist/{controller → core/controller}/ObjectController.d.ts +10 -2
- package/dist/{controller → core/controller}/ObjectController.js +8 -8
- package/dist/{controller → core/controller}/SettingsController.d.ts +28 -4
- package/dist/{controller → core/controller}/SettingsController.js +0 -25
- package/dist/{controller → core/controller}/SharedContentController.d.ts +31 -3
- package/dist/{controller → core/controller}/SharedContentController.js +77 -26
- package/dist/core/controller/VoiceController.d.ts +9 -0
- package/dist/{controller → core/controller}/VoiceController.js +11 -4
- package/dist/core/core.d.ts +14 -0
- package/dist/core/core.js +8 -0
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.d.ts +3 -3
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.js +26 -9
- package/dist/fromRimori/PluginTypes.d.ts +174 -0
- package/dist/hooks/UseChatHook.d.ts +2 -1
- package/dist/hooks/UseChatHook.js +6 -4
- package/dist/hooks/UseLogger.d.ts +30 -0
- package/dist/hooks/UseLogger.js +122 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +5 -3
- package/dist/plugin/AccomplishmentHandler.d.ts +1 -1
- package/dist/plugin/AccomplishmentHandler.js +1 -1
- package/dist/plugin/AudioController.d.ts +37 -0
- package/dist/plugin/AudioController.js +68 -0
- package/dist/plugin/Logger.d.ts +68 -0
- package/dist/plugin/Logger.js +256 -0
- package/dist/plugin/LoggerExample.d.ts +16 -0
- package/dist/plugin/LoggerExample.js +140 -0
- package/dist/plugin/PluginController.d.ts +30 -5
- package/dist/plugin/PluginController.js +182 -53
- package/dist/plugin/RimoriClient.d.ts +68 -21
- package/dist/plugin/RimoriClient.js +88 -41
- package/dist/plugin/StandaloneClient.d.ts +1 -0
- package/dist/plugin/StandaloneClient.js +24 -10
- package/dist/plugin/ThemeSetter.d.ts +2 -1
- package/dist/plugin/ThemeSetter.js +13 -7
- package/dist/providers/PluginProvider.d.ts +4 -1
- package/dist/providers/PluginProvider.js +39 -13
- package/dist/utils/Language.d.ts +2 -1
- package/dist/utils/Language.js +4 -2
- package/dist/utils/audioFormats.d.ts +26 -0
- package/dist/utils/audioFormats.js +67 -0
- package/dist/utils/difficultyConverter.js +1 -1
- package/dist/utils/endpoint.d.ts +2 -0
- package/dist/utils/endpoint.js +2 -0
- package/dist/worker/WorkerSetup.d.ts +3 -2
- package/dist/worker/WorkerSetup.js +22 -65
- package/example/docs/devdocs.md +231 -0
- package/example/docs/overview.md +29 -0
- package/example/docs/userdocs.md +123 -0
- package/example/rimori.config.ts +89 -0
- package/example/worker/vite.config.ts +23 -0
- package/example/worker/worker.ts +11 -0
- package/package.json +16 -9
- package/src/cli/scripts/init/dev-registration.ts +192 -0
- package/src/cli/scripts/init/env-setup.ts +44 -0
- package/src/cli/scripts/init/file-operations.ts +58 -0
- package/src/cli/scripts/init/html-cleaner.ts +48 -0
- package/src/cli/scripts/init/main.ts +172 -0
- package/src/cli/scripts/init/package-setup.ts +117 -0
- package/src/cli/scripts/init/router-transformer.ts +329 -0
- package/src/cli/scripts/init/tailwind-config.ts +75 -0
- package/src/cli/scripts/init/vite-config.ts +73 -0
- package/src/cli/scripts/release/release-config-upload.ts +114 -0
- package/src/cli/scripts/release/release-db-update.ts +97 -0
- package/src/cli/scripts/release/release-file-upload.ts +138 -0
- package/src/cli/scripts/release/release.ts +69 -0
- package/src/cli/types/DatabaseTypes.ts +117 -0
- package/src/components/ai/Assistant.tsx +5 -5
- package/src/components/ai/Avatar.tsx +25 -8
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +1 -1
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +50 -35
- package/src/components/ai/utils.ts +0 -2
- package/src/components/audio/Playbutton.tsx +4 -4
- package/src/{core → components}/components/ContextMenu.tsx +56 -12
- package/src/components.ts +6 -6
- package/src/core/controller/AIController.ts +283 -0
- package/src/core/controller/ObjectController.ts +115 -0
- package/src/{controller → core/controller}/SettingsController.ts +29 -29
- package/src/{controller → core/controller}/SharedContentController.ts +91 -29
- package/src/core/controller/VoiceController.ts +31 -0
- package/src/core/core.ts +16 -0
- package/src/{plugin/fromRimori → fromRimori}/EventBus.ts +29 -11
- package/src/fromRimori/PluginTypes.ts +205 -0
- package/src/hooks/UseChatHook.ts +8 -5
- package/src/index.ts +6 -3
- package/src/plugin/AccomplishmentHandler.ts +1 -1
- package/src/plugin/AudioController.ts +58 -0
- package/src/plugin/Logger.ts +324 -0
- package/src/plugin/PluginController.ts +203 -63
- package/src/plugin/RimoriClient.ts +127 -55
- package/src/plugin/StandaloneClient.ts +30 -11
- package/src/plugin/ThemeSetter.ts +16 -9
- package/src/providers/PluginProvider.tsx +46 -13
- package/src/utils/Language.ts +4 -2
- package/src/utils/difficultyConverter.ts +3 -3
- package/src/utils/endpoint.ts +2 -0
- package/src/worker/WorkerSetup.ts +13 -60
- package/dist/components/PluginController.d.ts +0 -21
- package/dist/components/PluginController.js +0 -116
- package/dist/controller/AIController.d.ts +0 -23
- package/dist/controller/AIController.js +0 -93
- package/dist/controller/SidePluginController.d.ts +0 -3
- package/dist/controller/SidePluginController.js +0 -31
- package/dist/controller/VoiceController.d.ts +0 -10
- package/dist/core.d.ts +0 -7
- package/dist/core.js +0 -7
- package/dist/plugin/ContextMenu.d.ts +0 -17
- package/dist/plugin/ContextMenu.js +0 -45
- package/dist/plugin/fromRimori/PluginTypes.d.ts +0 -48
- package/dist/plugin/fromRimori/SupabaseHandler.d.ts +0 -13
- package/dist/plugin/fromRimori/SupabaseHandler.js +0 -55
- package/dist/providers/PluginController.d.ts +0 -21
- package/dist/providers/PluginController.js +0 -116
- package/dist/types/Actions.d.ts +0 -4
- package/dist/types/Actions.js +0 -1
- package/src/controller/AIController.ts +0 -112
- package/src/controller/ObjectController.ts +0 -107
- package/src/controller/SidePluginController.ts +0 -25
- package/src/controller/VoiceController.ts +0 -26
- package/src/core.ts +0 -8
- package/src/plugin/fromRimori/PluginTypes.ts +0 -64
- package/src/types/Actions.ts +0 -6
- /package/dist/{core → components}/components/ContextMenu.d.ts +0 -0
- /package/dist/{plugin/fromRimori → fromRimori}/PluginTypes.js +0 -0
- /package/src/{plugin/fromRimori → fromRimori}/readme.md +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Updates the tailwind.config.ts file to set darkMode to "class" and add the Rimori client package to content.
|
|
5
|
+
*/
|
|
6
|
+
export function updateTailwindConfig() {
|
|
7
|
+
console.log('Updating Tailwind CSS configuration...');
|
|
8
|
+
const tailwindConfigPath = path.resolve('./tailwind.config.ts');
|
|
9
|
+
if (!fs.existsSync(tailwindConfigPath)) {
|
|
10
|
+
console.log('Warning: tailwind.config.ts not found, skipping Tailwind CSS update');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const configContent = fs.readFileSync(tailwindConfigPath, 'utf8');
|
|
15
|
+
let updatedContent = configContent;
|
|
16
|
+
// Set darkMode to "class" if it exists, otherwise add it
|
|
17
|
+
if (updatedContent.includes('darkMode:')) {
|
|
18
|
+
updatedContent = updatedContent.replace(/darkMode:\s*\[?"[^"]*"?\]?,?/g, 'darkMode: ["class"],');
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Add darkMode after the opening brace
|
|
22
|
+
updatedContent = updatedContent.replace(/export default \{/, 'export default {\n darkMode: ["class"],');
|
|
23
|
+
}
|
|
24
|
+
// Add Rimori client package to content array if not already present
|
|
25
|
+
if (!updatedContent.includes('node_modules/@rimori/client')) {
|
|
26
|
+
// Find the content array and add the Rimori client path
|
|
27
|
+
if (updatedContent.includes('content:')) {
|
|
28
|
+
// More precise regex to handle the content array properly
|
|
29
|
+
updatedContent = updatedContent.replace(/(content:\s*\[)([\s\S]*?)(\])/, (match, start, content, end) => {
|
|
30
|
+
// Clean up any existing double commas first
|
|
31
|
+
let cleanContent = content.replace(/,\s*,/g, ',');
|
|
32
|
+
// Remove trailing comma and whitespace
|
|
33
|
+
cleanContent = cleanContent.replace(/,\s*$/, '');
|
|
34
|
+
// Add the new path with proper formatting
|
|
35
|
+
const newPath = '"node_modules/@rimori/client/dist/components/**/*.{js,jsx}"';
|
|
36
|
+
// If content is not empty, add comma before new entry
|
|
37
|
+
if (cleanContent.trim()) {
|
|
38
|
+
return `${start}${cleanContent},\n ${newPath}\n ${end}`;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return `${start}\n ${newPath}\n ${end}`;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Add content array if it doesn't exist
|
|
47
|
+
updatedContent = updatedContent.replace(/darkMode: \["class"\],/, 'darkMode: ["class"],\n content: [\n "./src/**/*.{js,jsx,ts,tsx}",\n "node_modules/@rimori/client/dist/components/**/*.{js,jsx}"\n ],');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
fs.writeFileSync(tailwindConfigPath, updatedContent, 'utf8');
|
|
51
|
+
console.log('✅ Tailwind CSS configuration updated');
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.warn(`Warning: Could not update tailwind.config.ts: ${error instanceof Error ? error.message : error}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates the vite.config.ts file to set the base property.
|
|
3
|
+
* @param param
|
|
4
|
+
* @param param.basePath - The base path to set in vite config (defaults to './')
|
|
5
|
+
* @param param.configPath - Path to the vite.config.ts file (defaults to './vite.config.ts')
|
|
6
|
+
* @throws {Error} if vite.config.ts file is not found or cannot be modified.
|
|
7
|
+
*/
|
|
8
|
+
export declare function updateViteConfigBase({ basePath, configPath }?: {
|
|
9
|
+
basePath?: string;
|
|
10
|
+
configPath?: string;
|
|
11
|
+
}): void;
|
|
12
|
+
/**
|
|
13
|
+
* Reads the current base value from vite.config.ts.
|
|
14
|
+
* @param param
|
|
15
|
+
* @param param.configPath - Path to the vite.config.ts file (defaults to './vite.config.ts')
|
|
16
|
+
* @returns The current base value or null if not found.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getCurrentViteBase({ configPath }?: {
|
|
19
|
+
configPath?: string;
|
|
20
|
+
}): string | null;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Updates the vite.config.ts file to set the base property.
|
|
5
|
+
* @param param
|
|
6
|
+
* @param param.basePath - The base path to set in vite config (defaults to './')
|
|
7
|
+
* @param param.configPath - Path to the vite.config.ts file (defaults to './vite.config.ts')
|
|
8
|
+
* @throws {Error} if vite.config.ts file is not found or cannot be modified.
|
|
9
|
+
*/
|
|
10
|
+
export function updateViteConfigBase({ basePath = './', configPath = './vite.config.ts' } = {}) {
|
|
11
|
+
const viteConfigPath = path.resolve(configPath);
|
|
12
|
+
if (!fs.existsSync(viteConfigPath)) {
|
|
13
|
+
throw new Error(`vite.config.ts not found at ${viteConfigPath}`);
|
|
14
|
+
}
|
|
15
|
+
let configContent = fs.readFileSync(viteConfigPath, 'utf8');
|
|
16
|
+
// Check if base property already exists
|
|
17
|
+
const baseRegex = /base:\s*['"][^'"]*['"],?\s*/;
|
|
18
|
+
const hasBase = baseRegex.test(configContent);
|
|
19
|
+
if (hasBase) {
|
|
20
|
+
// Update existing base property
|
|
21
|
+
configContent = configContent.replace(baseRegex, `base: '${basePath}',`);
|
|
22
|
+
console.log(`Updated existing base property in vite.config.ts to '${basePath}'`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Add base property before server config
|
|
26
|
+
const serverRegex = /(\s*)(server:\s*\{)/;
|
|
27
|
+
const serverMatch = configContent.match(serverRegex);
|
|
28
|
+
if (serverMatch) {
|
|
29
|
+
const indentation = serverMatch[1] || ' '; // Use existing indentation or default to 2 spaces
|
|
30
|
+
const replacement = `${indentation}base: '${basePath}',${indentation}${serverMatch[2]}`;
|
|
31
|
+
configContent = configContent.replace(serverRegex, replacement);
|
|
32
|
+
console.log(`Added base property to vite.config.ts with value '${basePath}'`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
throw new Error('Could not find server config in vite.config.ts to add base property before it');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
fs.writeFileSync(viteConfigPath, configContent, 'utf8');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Reads the current base value from vite.config.ts.
|
|
42
|
+
* @param param
|
|
43
|
+
* @param param.configPath - Path to the vite.config.ts file (defaults to './vite.config.ts')
|
|
44
|
+
* @returns The current base value or null if not found.
|
|
45
|
+
*/
|
|
46
|
+
export function getCurrentViteBase({ configPath = './vite.config.ts' } = {}) {
|
|
47
|
+
const viteConfigPath = path.resolve(configPath);
|
|
48
|
+
if (!fs.existsSync(viteConfigPath)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const configContent = fs.readFileSync(viteConfigPath, 'utf8');
|
|
52
|
+
const baseMatch = configContent.match(/base:\s*['"]([^'"]*)['"]/);
|
|
53
|
+
return baseMatch ? baseMatch[1] : null;
|
|
54
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Config } from './release.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read and send the rimori configuration to the release endpoint
|
|
4
|
+
* @param config - Configuration object
|
|
5
|
+
*/
|
|
6
|
+
export declare function sendConfiguration(config: Config): Promise<string>;
|
|
7
|
+
export declare function releasePlugin(config: Config, release_id: string): Promise<void>;
|
|
@@ -0,0 +1,116 @@
|
|
|
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
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import ts from 'typescript';
|
|
13
|
+
/**
|
|
14
|
+
* Read and send the rimori configuration to the release endpoint
|
|
15
|
+
* @param config - Configuration object
|
|
16
|
+
*/
|
|
17
|
+
export function sendConfiguration(config) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const configPath = path.resolve('./rimori/rimori.config.ts');
|
|
20
|
+
// Check if config file exists
|
|
21
|
+
try {
|
|
22
|
+
yield fs.promises.access(configPath);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
throw new Error('Could not find rimori.config.ts in ./rimori/ directory');
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
let configObject;
|
|
29
|
+
// Use TypeScript compiler to transpile and load
|
|
30
|
+
const configContent = yield fs.promises.readFile(configPath, 'utf8');
|
|
31
|
+
// Transpile TypeScript to JavaScript
|
|
32
|
+
const result = ts.transpile(configContent, {
|
|
33
|
+
target: ts.ScriptTarget.ES2020,
|
|
34
|
+
module: ts.ModuleKind.ES2020
|
|
35
|
+
});
|
|
36
|
+
// Create a temporary file to import the transpiled code
|
|
37
|
+
const tempFile = path.join(process.cwd(), 'temp_config.js');
|
|
38
|
+
yield fs.promises.writeFile(tempFile, result);
|
|
39
|
+
try {
|
|
40
|
+
// Use dynamic import to load the config
|
|
41
|
+
const config = yield import(`file://${tempFile}`);
|
|
42
|
+
configObject = config.default || config;
|
|
43
|
+
// Clean up temp file
|
|
44
|
+
yield fs.promises.unlink(tempFile);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// Clean up temp file even on error
|
|
48
|
+
try {
|
|
49
|
+
yield fs.promises.unlink(tempFile);
|
|
50
|
+
}
|
|
51
|
+
catch (e) { }
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
if (!configObject) {
|
|
55
|
+
throw new Error('Configuration object is empty or undefined');
|
|
56
|
+
}
|
|
57
|
+
console.log(`🚀 Sending configuration...`);
|
|
58
|
+
const requestBody = {
|
|
59
|
+
config: configObject,
|
|
60
|
+
version: config.version,
|
|
61
|
+
plugin_id: config.plugin_id,
|
|
62
|
+
release_channel: config.release_channel,
|
|
63
|
+
rimori_client_version: config.rimori_client_version,
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
const response = yield fetch(`${config.domain}/release`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: {
|
|
69
|
+
'Content-Type': 'application/json',
|
|
70
|
+
'Authorization': `Bearer ${config.token}`
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify(requestBody),
|
|
73
|
+
});
|
|
74
|
+
const responseText = yield response.text();
|
|
75
|
+
console.log('Configuration response status:', response.status);
|
|
76
|
+
console.log('Configuration response text:', responseText);
|
|
77
|
+
const responseData = JSON.parse(responseText);
|
|
78
|
+
if (response.ok) {
|
|
79
|
+
console.log('✅ Configuration deployed successfully!');
|
|
80
|
+
return responseData.release_id;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log('❌ Configuration failed!');
|
|
84
|
+
console.log('Error:', responseData.error || 'Unknown error');
|
|
85
|
+
console.log('Response data:', JSON.stringify(responseData, null, 2));
|
|
86
|
+
throw new Error('Configuration upload failed');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
console.log("error", e);
|
|
91
|
+
throw new Error("Error sending configuration");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error('❌ Error sending configuration:', error.message);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export function releasePlugin(config, release_id) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
const response = yield fetch(`${config.domain}/release/${release_id}/release`, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers: {
|
|
105
|
+
'Content-Type': 'application/json',
|
|
106
|
+
'Authorization': `Bearer ${config.token}`
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify({ plugin_id: config.plugin_id })
|
|
109
|
+
});
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
console.log("Response:", yield response.text());
|
|
112
|
+
throw new Error("Failed to release plugin");
|
|
113
|
+
}
|
|
114
|
+
console.log("✅ Plugin released successfully");
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import ts from 'typescript';
|
|
13
|
+
/**
|
|
14
|
+
* Read and send the database configuration to the release endpoint
|
|
15
|
+
* @param config - Configuration object
|
|
16
|
+
*/
|
|
17
|
+
export default function dbUpdate(config, release_id) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const dbConfigPath = path.resolve('./rimori/db.config.ts');
|
|
20
|
+
// Check if db config file exists
|
|
21
|
+
try {
|
|
22
|
+
yield fs.promises.access(dbConfigPath);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
console.warn('Could not find db.config.ts in ./rimori/ directory. Skipping database configuration upload.');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
let dbConfigObject;
|
|
30
|
+
// Use TypeScript compiler to transpile and load
|
|
31
|
+
const dbConfigContent = yield fs.promises.readFile(dbConfigPath, 'utf8');
|
|
32
|
+
// Transpile TypeScript to JavaScript
|
|
33
|
+
const result = ts.transpile(dbConfigContent, {
|
|
34
|
+
target: ts.ScriptTarget.ES2020,
|
|
35
|
+
module: ts.ModuleKind.ES2020
|
|
36
|
+
});
|
|
37
|
+
// Create a temporary file to import the transpiled code
|
|
38
|
+
const tempFile = path.join(process.cwd(), 'temp_db_config.js');
|
|
39
|
+
yield fs.promises.writeFile(tempFile, result);
|
|
40
|
+
try {
|
|
41
|
+
// Use dynamic import to load the db config
|
|
42
|
+
const dbConfig = yield import(`file://${tempFile}`);
|
|
43
|
+
dbConfigObject = Object.values(dbConfig);
|
|
44
|
+
// Clean up temp file
|
|
45
|
+
yield fs.promises.unlink(tempFile);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// Clean up temp file even on error
|
|
49
|
+
try {
|
|
50
|
+
yield fs.promises.unlink(tempFile);
|
|
51
|
+
}
|
|
52
|
+
catch (e) { }
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
if (!dbConfigObject) {
|
|
56
|
+
throw new Error('Database configuration object is empty or undefined');
|
|
57
|
+
}
|
|
58
|
+
console.log(`🗄️ Sending database configuration...`);
|
|
59
|
+
const requestBody = {
|
|
60
|
+
db_config: dbConfigObject,
|
|
61
|
+
version: config.version,
|
|
62
|
+
release_channel: config.release_channel,
|
|
63
|
+
plugin_id: config.plugin_id,
|
|
64
|
+
};
|
|
65
|
+
const response = yield fetch(`${config.domain}/release/${release_id}/db`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
'Authorization': `Bearer ${config.token}`
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify(requestBody),
|
|
72
|
+
}).catch((e) => {
|
|
73
|
+
console.log("error", e);
|
|
74
|
+
throw new Error("Error sending database configuration");
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const responseText = yield response.text().catch((e) => {
|
|
78
|
+
console.log("error", e);
|
|
79
|
+
throw new Error("Error sending database configuration");
|
|
80
|
+
});
|
|
81
|
+
const responseData = JSON.parse(responseText);
|
|
82
|
+
if (response.ok) {
|
|
83
|
+
console.log('✅ Database configuration deployed successfully!');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
console.log("responseData", responseData);
|
|
87
|
+
throw new Error(responseData.message);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
console.log("error", e);
|
|
92
|
+
throw new Error("Error sending database configuration");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error('❌ Error sending database configuration:', error.message);
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
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
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
/**
|
|
13
|
+
* Upload all files from a directory and its subdirectories to the release function
|
|
14
|
+
* @param config - Configuration object
|
|
15
|
+
*/
|
|
16
|
+
export function uploadDirectory(config, release_id) {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
const relativePath = './dist';
|
|
19
|
+
console.log(`📁 Preparing to upload files from ${relativePath}...`);
|
|
20
|
+
// Check if dist directory exists
|
|
21
|
+
try {
|
|
22
|
+
yield fs.promises.access(relativePath);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
throw new Error(`Directory ${relativePath} does not exist. Make sure to build your plugin first.`);
|
|
26
|
+
}
|
|
27
|
+
// Get all files recursively
|
|
28
|
+
const files = yield getAllFiles(relativePath);
|
|
29
|
+
if (files.length === 0) {
|
|
30
|
+
console.log('⚠️ No files found to upload');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.log(`🚀 Uploading ${files.length} files...`);
|
|
34
|
+
// Create FormData
|
|
35
|
+
const formData = new FormData();
|
|
36
|
+
// Add version and release channel data
|
|
37
|
+
formData.append('version', config.version);
|
|
38
|
+
formData.append('release_channel', config.release_channel);
|
|
39
|
+
formData.append('plugin_id', config.plugin_id);
|
|
40
|
+
// Create path mapping with IDs as keys
|
|
41
|
+
const pathMapping = {};
|
|
42
|
+
for (let i = 0; i < files.length; i++) {
|
|
43
|
+
const filePath = files[i];
|
|
44
|
+
try {
|
|
45
|
+
const fileContent = yield fs.promises.readFile(filePath);
|
|
46
|
+
const relativePath = path.relative('./dist', filePath);
|
|
47
|
+
const contentType = getContentType(filePath);
|
|
48
|
+
// Generate unique ID for this file
|
|
49
|
+
const fileId = `file_${i}`;
|
|
50
|
+
// Add to path mapping using ID as key
|
|
51
|
+
pathMapping[fileId] = relativePath;
|
|
52
|
+
// Create a Blob with the file content and content type
|
|
53
|
+
const blob = new Blob([fileContent], { type: contentType });
|
|
54
|
+
// Add file to FormData with ID_filename format
|
|
55
|
+
const fileName = `${fileId}_${path.basename(filePath)}`;
|
|
56
|
+
formData.append('files', blob, fileName);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(`❌ Error reading file ${filePath}:`, error.message);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Add path mapping to FormData
|
|
64
|
+
formData.append('path_mapping', JSON.stringify(pathMapping));
|
|
65
|
+
// Upload to the release endpoint
|
|
66
|
+
const response = yield fetch(`${config.domain}/release/${release_id}/files`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: { 'Authorization': `Bearer ${config.token}` },
|
|
69
|
+
body: formData,
|
|
70
|
+
});
|
|
71
|
+
if (response.ok) {
|
|
72
|
+
console.log('✅ Files uploaded successfully!');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const errorText = yield response.text();
|
|
76
|
+
console.log('❌ File upload failed!');
|
|
77
|
+
console.log('Response:', errorText);
|
|
78
|
+
throw new Error(`File upload failed with status ${response.status}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Recursively get all files from a directory
|
|
84
|
+
*/
|
|
85
|
+
function getAllFiles(dirPath) {
|
|
86
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
const files = [];
|
|
88
|
+
function traverse(currentPath) {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const entries = yield fs.promises.readdir(currentPath, { withFileTypes: true });
|
|
91
|
+
for (const entry of entries) {
|
|
92
|
+
const fullPath = path.join(currentPath, entry.name);
|
|
93
|
+
if (entry.isDirectory()) {
|
|
94
|
+
yield traverse(fullPath);
|
|
95
|
+
}
|
|
96
|
+
else if (entry.isFile()) {
|
|
97
|
+
files.push(fullPath);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
yield traverse(dirPath);
|
|
103
|
+
return files;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get content type based on file extension
|
|
108
|
+
*/
|
|
109
|
+
function getContentType(filePath) {
|
|
110
|
+
var _a;
|
|
111
|
+
const ext = (_a = filePath.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
112
|
+
const contentTypes = {
|
|
113
|
+
html: 'text/html',
|
|
114
|
+
css: 'text/css',
|
|
115
|
+
js: 'application/javascript',
|
|
116
|
+
json: 'application/json',
|
|
117
|
+
md: 'text/markdown',
|
|
118
|
+
txt: 'text/plain',
|
|
119
|
+
png: 'image/png',
|
|
120
|
+
jpg: 'image/jpeg',
|
|
121
|
+
jpeg: 'image/jpeg',
|
|
122
|
+
gif: 'image/gif',
|
|
123
|
+
svg: 'image/svg+xml',
|
|
124
|
+
pdf: 'application/pdf',
|
|
125
|
+
ico: 'image/x-icon',
|
|
126
|
+
mp3: 'audio/mpeg',
|
|
127
|
+
wav: 'audio/wav',
|
|
128
|
+
ogg: 'audio/ogg',
|
|
129
|
+
m4a: 'audio/mp4',
|
|
130
|
+
webp: 'image/webp',
|
|
131
|
+
};
|
|
132
|
+
const contentType = contentTypes[ext || ''];
|
|
133
|
+
if (!contentType)
|
|
134
|
+
throw new Error(`Unsupported file type: ${ext}`);
|
|
135
|
+
return contentType;
|
|
136
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Usage:
|
|
4
|
+
* rimori-release <release_channel>
|
|
5
|
+
*
|
|
6
|
+
* Environment variables required:
|
|
7
|
+
* RIMORI_TOKEN - Your Rimori token
|
|
8
|
+
* RIMORI_PLUGIN - Your plugin ID
|
|
9
|
+
*
|
|
10
|
+
* Make sure to install dependencies:
|
|
11
|
+
* npm install node-fetch form-data ts-node typescript
|
|
12
|
+
*/
|
|
13
|
+
import 'dotenv/config';
|
|
14
|
+
declare const config: {
|
|
15
|
+
version: any;
|
|
16
|
+
release_channel: string;
|
|
17
|
+
plugin_id: any;
|
|
18
|
+
token: string;
|
|
19
|
+
domain: string;
|
|
20
|
+
rimori_client_version: any;
|
|
21
|
+
};
|
|
22
|
+
export type Config = typeof config;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Usage:
|
|
4
|
+
* rimori-release <release_channel>
|
|
5
|
+
*
|
|
6
|
+
* Environment variables required:
|
|
7
|
+
* RIMORI_TOKEN - Your Rimori token
|
|
8
|
+
* RIMORI_PLUGIN - Your plugin ID
|
|
9
|
+
*
|
|
10
|
+
* Make sure to install dependencies:
|
|
11
|
+
* npm install node-fetch form-data ts-node typescript
|
|
12
|
+
*/
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
import 'dotenv/config';
|
|
23
|
+
import fs from 'fs';
|
|
24
|
+
import path from 'path';
|
|
25
|
+
import dbUpdate from './release-db-update.js';
|
|
26
|
+
import { uploadDirectory } from './release-file-upload.js';
|
|
27
|
+
import { releasePlugin, sendConfiguration } from './release-config-upload.js';
|
|
28
|
+
// Read version from package.json
|
|
29
|
+
const packageJson = JSON.parse(fs.readFileSync(path.resolve('./package.json'), 'utf8'));
|
|
30
|
+
const { version, r_id: pluginId } = packageJson;
|
|
31
|
+
const RIMORI_TOKEN = process.env.RIMORI_TOKEN;
|
|
32
|
+
if (!RIMORI_TOKEN)
|
|
33
|
+
throw new Error('RIMORI_TOKEN is not set');
|
|
34
|
+
if (!pluginId)
|
|
35
|
+
throw new Error('The plugin id (r_id) is not set in package.json');
|
|
36
|
+
const [releaseChannel] = process.argv.slice(2);
|
|
37
|
+
if (!releaseChannel) {
|
|
38
|
+
console.error('Usage: rimori-release <release_channel>');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const config = {
|
|
42
|
+
version,
|
|
43
|
+
release_channel: releaseChannel,
|
|
44
|
+
plugin_id: pluginId,
|
|
45
|
+
token: RIMORI_TOKEN,
|
|
46
|
+
domain: process.env.RIMORI_BACKEND_URL || "https://api.rimori.se",
|
|
47
|
+
rimori_client_version: packageJson.dependencies['@rimori/client'].replace('^', ''),
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Main release process
|
|
51
|
+
*/
|
|
52
|
+
function releaseProcess() {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
try {
|
|
55
|
+
console.log(`🚀 Releasing ${config.plugin_id} to ${config.release_channel}...`);
|
|
56
|
+
// First send the configuration
|
|
57
|
+
const release_id = yield sendConfiguration(config);
|
|
58
|
+
yield dbUpdate(config, release_id);
|
|
59
|
+
// Then upload the files
|
|
60
|
+
yield uploadDirectory(config, release_id);
|
|
61
|
+
// Then release the plugin
|
|
62
|
+
yield releasePlugin(config, release_id);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.log("❌ Error:", error.message);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
releaseProcess();
|