Merge pull request #383 from gnh1201/dev
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
Deploy Jekyll with GitHub Pages dependencies preinstalled / build (push) Has been cancelled
Deploy Jekyll with GitHub Pages dependencies preinstalled / deploy (push) Has been cancelled

Refactor file deployment logic in HandleTargetFilePath
This commit is contained in:
Namhyeon Go 2026-01-19 20:33:16 +09:00 committed by GitHub
commit b1d2f02dee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 185 additions and 71 deletions

View File

@ -201,57 +201,137 @@ namespace WelsonJS.Launcher
private static void HandleTargetFilePath(string filePath)
{
string fileExtension = Path.GetExtension(filePath);
if (string.IsNullOrWhiteSpace(filePath))
throw new ArgumentException("filePath is null or empty.", nameof(filePath));
if (String.IsNullOrEmpty(fileExtension))
{
throw new ArgumentException("The file extension is null or empty");
}
if (!File.Exists(filePath))
throw new FileNotFoundException("Target file not found.", filePath);
if (fileExtension.Equals(".zip", StringComparison.OrdinalIgnoreCase))
{
string ext = Path.GetExtension(filePath);
if (string.IsNullOrEmpty(ext))
throw new ArgumentException("The file extension is null or empty.", nameof(filePath));
if (ext.Equals(".zip", StringComparison.OrdinalIgnoreCase))
throw new NotImplementedException("Not implemented yet.");
}
if (fileExtension.Equals(".js", StringComparison.OrdinalIgnoreCase))
if (!ext.Equals(".js", StringComparison.OrdinalIgnoreCase))
throw new NotSupportedException($"Unsupported file type: {ext}");
string instanceId = Guid.NewGuid().ToString();
string workingDirectory = CreateInstanceDirectory(instanceId);
string appRoot = GetAppRootDirectory();
if (string.IsNullOrWhiteSpace(appRoot) || !Directory.Exists(appRoot))
throw new DirectoryNotFoundException($"Application root not found: {appRoot}");
DeployBaseFiles(appRoot, workingDirectory);
DeployOptionalDataFiles(appRoot, workingDirectory);
DeployEntrypoint(filePath, workingDirectory);
RecordFirstDeployTime(workingDirectory, instanceId);
RunCommandPrompt(
workingDirectory: workingDirectory,
entryFileName: "app.js",
scriptName: "bootstrap",
isConsoleApplication: true,
isInteractiveServiceApplication: false
);
}
private static void DeployBaseFiles(string appRoot, string workingDirectory)
{
CopyFile(
Path.Combine(appRoot, "app.js"),
Path.Combine(workingDirectory, "app.js"),
isRequired: true
);
CopyDirectoryRecursive(
Path.Combine(appRoot, "app", "assets", "js"),
Path.Combine(workingDirectory, "app", "assets", "js"),
isRequired: true
);
CopyDirectoryRecursive(
Path.Combine(appRoot, "lib"),
Path.Combine(workingDirectory, "lib"),
isRequired: true
);
}
private static void DeployOptionalDataFiles(string appRoot, string workingDirectory)
{
CopyFile(
Path.Combine(appRoot, "data", "apikey.json"),
Path.Combine(workingDirectory, "data", "apikey.json"),
isRequired: false
);
CopyFile(
Path.Combine(appRoot, "data", "available_proxies.json"),
Path.Combine(workingDirectory, "data", "available_proxies.json"),
isRequired: false
);
CopyFile(
Path.Combine(appRoot, "data", "filetypes.json"),
Path.Combine(workingDirectory, "data", "filetypes.json"),
isRequired: false
);
}
private static void DeployEntrypoint(string sourceJsPath, string workingDirectory)
{
CopyFile(
sourceJsPath,
Path.Combine(workingDirectory, "bootstrap.js"),
isRequired: true
);
}
private static void CopyDirectoryRecursive(
string sourceDir,
string destinationDir,
bool isRequired = false
)
{
if (!Directory.Exists(sourceDir))
{
string instanceId = Guid.NewGuid().ToString();
string workingDirectory = CreateInstanceDirectory(instanceId);
string appRoot = GetAppRootDirectory();
string appBaseSource = Path.Combine(appRoot, "app.js");
if (!File.Exists(appBaseSource))
{
throw new FileNotFoundException("app.js not found in application root.", appBaseSource);
}
string appBaseDestination = Path.Combine(workingDirectory, "app.js");
File.Copy(appBaseSource, appBaseDestination, overwrite: true);
string assetsSource = Path.Combine(appRoot, "app", "assets", "js");
string assetsDestination = Path.Combine(workingDirectory, "app", "assets", "js");
CopyDirectoryRecursive(assetsSource, assetsDestination);
string libSource = Path.Combine(appRoot, "lib");
string libDestination = Path.Combine(workingDirectory, "lib");
CopyDirectoryRecursive(libSource, libDestination);
string entrypointDestination = Path.Combine(workingDirectory, "bootstrap.js");
File.Copy(filePath, entrypointDestination, overwrite: true);
RecordFirstDeployTime(workingDirectory, instanceId);
RunCommandPrompt(
workingDirectory: workingDirectory,
entryFileName: "app.js",
scriptName: "bootstrap",
isConsoleApplication: true,
isInteractiveServiceApplication: false
);
if (isRequired)
throw new DirectoryNotFoundException($"Required directory not found: {sourceDir}");
return;
}
throw new NotSupportedException($"Unsupported file type: {fileExtension}");
Directory.CreateDirectory(destinationDir);
foreach (string file in Directory.GetFiles(sourceDir))
{
string destFile = Path.Combine(destinationDir, Path.GetFileName(file));
File.Copy(file, destFile, overwrite: true);
}
foreach (string subDir in Directory.GetDirectories(sourceDir))
{
string destSubDir = Path.Combine(destinationDir, Path.GetFileName(subDir));
CopyDirectoryRecursive(subDir, destSubDir, isRequired);
}
}
private static void CopyFile(string sourcePath, string destinationPath, bool isRequired)
{
if (!File.Exists(sourcePath))
{
if (isRequired)
throw new FileNotFoundException("Required file not found.", sourcePath);
return;
}
string parent = Path.GetDirectoryName(destinationPath);
if (!string.IsNullOrEmpty(parent))
Directory.CreateDirectory(parent);
File.Copy(sourcePath, destinationPath, overwrite: true);
}
private static string GetAppRootDirectory()
@ -299,33 +379,6 @@ namespace WelsonJS.Launcher
return workingDirectory;
}
private static void CopyDirectoryRecursive(string sourceDir, string destDir)
{
if (!Directory.Exists(sourceDir))
{
throw new DirectoryNotFoundException("Source directory not found: " + sourceDir);
}
Directory.CreateDirectory(destDir);
foreach (var file in Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories))
{
string normalizedSource = sourceDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
string relativePath = file.Substring(normalizedSource.Length + 1).TrimStart(
Path.DirectorySeparatorChar,
Path.AltDirectorySeparatorChar
);
string targetPath = Path.Combine(destDir, relativePath);
string targetDir = Path.GetDirectoryName(targetPath);
if (!Directory.Exists(targetDir))
{
Directory.CreateDirectory(targetDir);
}
File.Copy(file, targetPath, overwrite: true);
}
}
public static void RunCommandPrompt(string workingDirectory, string entryFileName, string scriptName, bool isConsoleApplication = false, bool isInteractiveServiceApplication = false)
{
if (!isConsoleApplication)

View File

@ -8,6 +8,7 @@
"deepseek": "file:data/deepseek_apikey.txt",
"moonshot": "file:data/moonshot_apikey.txt",
"clovastudio": "file:data/clovastudio_apikey.txt",
"friendiai": "file:data/friendiai_apikey.txt",
"catswords-ai": "file:data/catswords_ai_apikey.txt",
"scrapeops": "file:data/scrapeops_apikey.txt",
"serpapi": "file:data/serpapi_apikey.txt",

View File

@ -17,6 +17,7 @@
// - Moonshot: https://kimi.moonshot.cn/user/agreement/userPrivacy
// - AlibabaCloud: https://www.alibabacloud.com/help/en/legal/latest/alibaba-cloud-international-website-privacy-policy
// - ClovaStudio: https://clova-x.naver.com/ai_policies
// - FriendIAI: https://friendli.ai/privacypolicy
// - Catswords AI: https://policy.catswords.social/site_terms.html
//
var HTTP = require("lib/http");
@ -428,6 +429,65 @@ var ENGINE_PROFILES = {
}
}
},
"friendiai": {
"type": "llm",
"availableModels": [
"LGAI-EXAONE/K-EXAONE-236B-A23B",
"MiniMaxAI/MiniMax-M2.1",
"zai-org/GLM-4.6",
"meta-llama-3.1-8b-instruct",
"mistralai/Magistral-Small-2506",
"skt/A.X-3.1",
"Qwen/Qwen3-235B-A22B-Thinking-2507",
"Qwen/Qwen3-235B-A22B-Instruct-2507",
"meta-llama-3.3-70b-instruct",
"mistralai/Devstral-Small-2505",
"google/gemma-3-27b-it",
"Qwen/Qwen3-32B",
"meta-llama/Llama-4-Scout-17B-16E-Instruct",
"Qwen/Qwen3-30B-A3B",
"meta-llama/Llama-4-Maverick-17B-128E-Instruct",
"mistralai/Mistral-Small-3.1-24B-Instruct-2503",
"deepseek-ai/DeepSeek-V3.1",
"skt/A.X-4.0",
"naver-hyperclovax/HyperCLOVAX-SEED-Think-14B",
"LGAI-EXAONE/EXAONE-4.0.1-32B"
],
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer {apikey}"
},
"url": "https://api.friendli.ai/serverless/v1",
"wrap": function(model, message, temperature) {
return {
"model": model,
"messages": [{
"role": "system",
"content": BIAS_MESSAGE
}, {
"role": "user",
"content": message
}],
"temperature": temperature,
"stream": false,
"parse_reasoning": true,
"chat_template_kwargs": {
"enable_thinking": true
}
};
},
"callback": function(response) {
if ("error" in response) {
return ["Error: " + response.error.message];
} else {
return response.choices.reduce(function(a, x) {
a.push(x.message.content);
return a;
}, []);
}
}
},
"catswords-ai": {
"type": "llm",
"availableModels": [
@ -553,7 +613,7 @@ exports.create = function() {
return new LanguageInferenceEngine();
};
exports.VERSIONINFO = "Language Inference Engine integration version 0.1.11";
exports.VERSIONINFO = "Language Inference Engine integration version 0.1.12";
exports.AUTHOR = "gnh1201@catswords.re.kr";
exports.global = global;
exports.require = global.require;