From 6c18f58fc008d3b755893d38147140134e6505c3 Mon Sep 17 00:00:00 2001 From: Nikita <61884745+dakln@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:10:04 +0500 Subject: [PATCH] v1.1.12 Moved base_addon folder to fetch from github --- addon_base/plugin/plugin.js | 3 ++ cli.ts | 33 ++++++------ cli/create-addon-structure.ts | 96 +++++++++++++++++++++++++++-------- cli/get-addon-icon.ts | 16 +++--- cli/main.ts | 11 ++-- cli/paths.ts | 6 ++- deno.json | 3 +- deps.ts | 52 +------------------ 8 files changed, 115 insertions(+), 105 deletions(-) diff --git a/addon_base/plugin/plugin.js b/addon_base/plugin/plugin.js index 5577d43..db69dfa 100644 --- a/addon_base/plugin/plugin.js +++ b/addon_base/plugin/plugin.js @@ -10,6 +10,9 @@ const SCRIPTS = []; const FILES = []; +const ICON_NAME = ""; +const ICON_TYPE = ""; + const SDK = globalThis.SDK; const PLUGIN_CLASS = SDK.Plugins[ADDON_ID] = class LostPlugin extends SDK.IPluginBase { diff --git a/cli.ts b/cli.ts index 391c034..aa82430 100644 --- a/cli.ts +++ b/cli.ts @@ -1,29 +1,17 @@ #!/usr/bin/env deno run --allow-read --allow-write --unstable -import { getLibraryDirectory, path } from "./deps.ts" import { parseArgs } from "jsr:@std/cli@1.0.6"; import { Colors } from "./deps.ts"; import { buildAddon } from "./cli/main.ts"; import type { AddonType } from "./lib/common.ts"; -//const __dirname: string = getLibraryDirectory(); - -let __dirname: string //= path.dirname(path.fromFileUrl(import.meta.url)); - -if (import.meta.url.startsWith('file:')) { - __dirname = path.fromFileUrl(import.meta.url); - } else { - // Обработка https: URL - __dirname = new URL(import.meta.url).pathname; - } - -const VERSION = '1.1.11' +const VERSION = '1.1.12' type LostCommand = 'none' | 'help' | 'version' | 'build' | 'create' | 'serve'; async function main() { const { _, ...flags } = parseArgs(Deno.args, { - boolean: ["plugin"], - alias: {p: "plugin"}, + boolean: ["plugin", "local-base"], + alias: {p: "plugin", l: "local-base"}, "--": true, }); @@ -48,10 +36,20 @@ async function main() { } break; case 'build': - await buildAddon({ serve: false, LIB_PATH: __dirname }); + if (!flags['local-base']) { + await buildAddon({ serve: false, localBase: false}); + } + if (flags['local-base']) { + await buildAddon({ serve: false, localBase: true }); + } break; case 'serve': - await buildAddon({ serve: true, LIB_PATH: __dirname }); + if (!flags['local-base']) { + await buildAddon({ serve: true, localBase: false}); + } + if (flags['local-base']) { + await buildAddon({ serve: true, localBase: true }); + } break; case 'none': console.error('❌', Colors.red(Colors.bold(`Unknown command:`)), Colors.italic(command)); @@ -97,5 +95,6 @@ function printHelp() { console.log(' ⚙️', Colors.gray(' --plugin, -p'), ' Creates a bare-bones for "plugin" addon type.'); console.log(` ${Colors.yellow('build')}`); + console.log(' ⚙️', Colors.gray(' --local-base, -c'), ' Builds addon with local addon base.'); console.log(` ${Colors.yellow('serve')}`); } \ No newline at end of file diff --git a/cli/create-addon-structure.ts b/cli/create-addon-structure.ts index c9f137c..43a925e 100644 --- a/cli/create-addon-structure.ts +++ b/cli/create-addon-structure.ts @@ -1,15 +1,16 @@ -import type { AddonType, IconType, LostConfig } from "../lib/common.ts"; +import type { AddonType, LostConfig } from "../lib/common.ts"; import type { PluginProperty } from "../lib/plugin-props.ts"; import type { LostCategoryDefault } from "../lib/entities.ts"; import type { AddonScript } from "./get-addon-scripts.ts"; import type { AddonFile } from "./get-addon-files.ts"; -import { BUILD_PATH } from "./paths.ts"; +import { ADDON_BASE_URL, BUILD_PATH, LOCAL_ADDON_BASE_PATH } from "./paths.ts"; import type { AddonIcon } from "./get-addon-icon.ts"; import { Project } from "./cli-deps.ts"; import { path } from '../deps.ts'; +import { LOGGER } from './misc.ts'; type AddonFiles = { - [K in AddonType]: [ + readonly [K in AddonType]: [ `c3runtime/${K}.js`, 'c3runtime/type.js', 'instance.js', @@ -36,7 +37,6 @@ const ADDON_FILES: AddonFiles = { } interface CreateAddonStructureOptions { - LIB_PATH: string; CONFIG: LostConfig<'plugin' | 'behavior'>; PLUGIN_PROPERTIES: PluginProperty[]; SCRIPTS: AddonScript[]; @@ -45,8 +45,8 @@ interface CreateAddonStructureOptions { ICON: AddonIcon; } -export async function createAddonStructure(options: CreateAddonStructureOptions) { - const {LIB_PATH, CONFIG, PLUGIN_PROPERTIES, SCRIPTS, FILES, ICON, CATEGORIES} = options; +export async function createAddonStructure(options: CreateAddonStructureOptions, localBase: boolean) { + const { CONFIG, PLUGIN_PROPERTIES, SCRIPTS, FILES, ICON, CATEGORIES } = options; try { await Deno.remove(BUILD_PATH, { recursive: true }); } catch (e) { @@ -68,24 +68,77 @@ export async function createAddonStructure(options: CreateAddonStructureOptions) }) }; - await Deno.copyFile(ICON.path, `${BUILD_PATH}/${ICON.filename}`); - let instanceFileData = await transpileTsToJs(`${Deno.cwd()}/Addon/Instance.ts`) as string; instanceFileData = instanceFileData.replace(/import\s+Config\s+from\s+["'](?:@config|\.\.\/lost\.config\.ts)["'];/, `const Config = ${JSON.stringify(CONFIG)};`); await Deno.writeTextFile(`${BUILD_PATH}/c3runtime/instance.js`, instanceFileData); - ADDON_FILES[CONFIG.Type].forEach(async (file) => { - const baseAddonDir = path.resolve(LIB_PATH, `addon_base/${CONFIG.Type}`); - let data = await Deno.readTextFile(`${baseAddonDir}/${file}`); - data = data - .replace(/const\s+ADDON_ID\s*=\s*"";/, `const ADDON_ID = ${JSON.stringify(CONFIG.AddonId)};`) - .replace(/const\s+CONFIG\s*=\s*\{\};/, `const CONFIG = ${JSON.stringify(CONFIG)};`) - .replace(/const\s+PLUGIN_PROPERTIES\s*=\s*\{\};/, `const PLUGIN_PROPERTIES = ${JSON.stringify(PLUGIN_PROPERTIES)};`) - .replace(/const\s+REMOTE_SCRIPTS\s*=\s*\[\];/, `const REMOTE_SCRIPTS = ${JSON.stringify(CONFIG.RemoteScripts || [])};`) - .replace(/const\s+SCRIPTS\s*=\s*\[\];/, `const SCRIPTS = ${JSON.stringify(SCRIPTS)};`) - .replace(/const\s+FILES\s*=\s*\[\];/, `const FILES = ${JSON.stringify(FILES)};`) - await Deno.writeTextFile(path.resolve(BUILD_PATH, file), data); - }) + if (!localBase) { + if (!ICON.isDefault) { + await Deno.copyFile(ICON.path, `${BUILD_PATH}/${ICON.filename}`); + } else { + const getIcon = await fetch(ICON.path); + + if (!getIcon.ok) { + // failed to get default icon + LOGGER.Error('build', `Failed to download default icon from url: ${ICON.path}`) + Deno.exit(); + } else { + const iconContent = await getIcon.text(); + await Deno.writeTextFile(`${BUILD_PATH}/${ICON.filename}`, iconContent) + } + } + + for await (const fileOrPath of ADDON_FILES[CONFIG.Type]) { + try { + const response = await fetch(`${ADDON_BASE_URL}/${CONFIG.Type}/${fileOrPath}`); + + if (!response.ok) { + LOGGER.Error('build', `Failed to fetch ${fileOrPath}`, response.statusText); + Deno.exit(); + } + + let fileContent = await response.text(); + + fileContent = fileContent + .replace(/const\s+ADDON_ID\s*=\s*"";/, `const ADDON_ID = ${JSON.stringify(CONFIG.AddonId)};`) + .replace(/const\s+CONFIG\s*=\s*\{\};/, `const CONFIG = ${JSON.stringify(CONFIG)};`) + .replace(/const\s+PLUGIN_PROPERTIES\s*=\s*\{\};/, `const PLUGIN_PROPERTIES = ${JSON.stringify(PLUGIN_PROPERTIES)};`) + .replace(/const\s+REMOTE_SCRIPTS\s*=\s*\[\];/, `const REMOTE_SCRIPTS = ${JSON.stringify(CONFIG.RemoteScripts || [])};`) + .replace(/const\s+SCRIPTS\s*=\s*\[\];/, `const SCRIPTS = ${JSON.stringify(SCRIPTS)};`) + .replace(/const\s+FILES\s*=\s*\[\];/, `const FILES = ${JSON.stringify(FILES)};`) + + await Deno.writeTextFile(path.resolve(BUILD_PATH, fileOrPath), fileContent); + + } catch (error) { + LOGGER.Error('build', `Error processing ${fileOrPath}:`, error); + Deno.exit(); + } + } + } else { + if (!ICON.isDefault) { + await Deno.copyFile(`${LOCAL_ADDON_BASE_PATH}/${ICON.filename}`, `${BUILD_PATH}/${ICON.filename}`); + } else { + const iconContent = await Deno.readTextFile(`${LOCAL_ADDON_BASE_PATH}/${ICON.filename}`); + await Deno.writeTextFile(`${BUILD_PATH}/${ICON.filename}`, iconContent); + } + + for await (const fileOrPath of ADDON_FILES[CONFIG.Type]) { + + let fileContent = await Deno.readTextFile(`${LOCAL_ADDON_BASE_PATH}/${CONFIG.Type}/${fileOrPath}`); + + fileContent = fileContent + .replace(/const\s+ADDON_ID\s*=\s*"";/, `const ADDON_ID = ${JSON.stringify(CONFIG.AddonId)};`) + .replace(/const\s+CONFIG\s*=\s*\{\};/, `const CONFIG = ${JSON.stringify(CONFIG)};`) + .replace(/const\s+PLUGIN_PROPERTIES\s*=\s*\{\};/, `const PLUGIN_PROPERTIES = ${JSON.stringify(PLUGIN_PROPERTIES)};`) + .replace(/const\s+REMOTE_SCRIPTS\s*=\s*\[\];/, `const REMOTE_SCRIPTS = ${JSON.stringify(CONFIG.RemoteScripts || [])};`) + .replace(/const\s+SCRIPTS\s*=\s*\[\];/, `const SCRIPTS = ${JSON.stringify(SCRIPTS)};`) + .replace(/const\s+FILES\s*=\s*\[\];/, `const FILES = ${JSON.stringify(FILES)};`) + .replace(/const\s+ICON_NAME\s*=\s*"";/, `const ICON_NAME = ${JSON.stringify(ICON.filename)};`) + .replace(/const\s+ICON_TYPE\s*=\s*"";/, `const ICON_TYPE = ${JSON.stringify(ICON.type)};`) + + await Deno.writeTextFile(path.resolve(BUILD_PATH, fileOrPath), fileContent); + } + } const setializedEntities = serializeEntities(CATEGORIES); @@ -95,6 +148,7 @@ export async function createAddonStructure(options: CreateAddonStructureOptions) await Deno.writeTextFile(path.resolve(BUILD_PATH, 'c3runtime', 'conditions.js'), entities); entities = `const ADDON_ID = ${JSON.stringify(CONFIG.AddonId)};\nconst C3 = globalThis.C3;\nC3.Plugins[ADDON_ID].Exps = ${setializedEntities.Expressions};`; await Deno.writeTextFile(path.resolve(BUILD_PATH, 'c3runtime', 'expressions.js'), entities); + } function serializeEntities(categories: LostCategoryDefault[]) { @@ -148,7 +202,7 @@ async function transpileTsToJs(filePath: string): Promise { const project = new Project({ compilerOptions: { target: 8, - module: 7 + module: 7 } }); const sourceFile = project.addSourceFileAtPath(filePath); diff --git a/cli/get-addon-icon.ts b/cli/get-addon-icon.ts index a6a99fb..2183198 100644 --- a/cli/get-addon-icon.ts +++ b/cli/get-addon-icon.ts @@ -1,21 +1,16 @@ -import { path } from '../deps.ts'; import type { IconType } from "../lib/common.ts"; import { LOGGER, WarningMessage } from "./misc.ts"; -import { ADDON_ICON_FOLDER_PATH } from "./paths.ts"; +import { ADDON_DEFAULT_ICON_URL, ADDON_ICON_FOLDER_PATH } from "./paths.ts"; export interface AddonIcon { filename: string; path: string; type: IconType; + isDefault?: true; } -interface GetAddonIconOptions { - LIB_PATH: string; -} - -export async function getAddonIcon(options: GetAddonIconOptions): Promise { - const { LIB_PATH } = options; +export async function getAddonIcon(): Promise { LOGGER.Searching('Looking for addon icon in png/svg format') for await (const entry of Deno.readDir(ADDON_ICON_FOLDER_PATH)) { if (entry.isFile) { @@ -34,7 +29,8 @@ export async function getAddonIcon(options: GetAddonIconOptions): Promise