diff --git a/TODO b/TODO index 10a17ce..9e36ace 100644 --- a/TODO +++ b/TODO @@ -53,7 +53,7 @@ Tests: - Disable step - View logs in realtime - editor full width (no sidebar) -- ask feedback on the editor (pause, confirm, etc.) +✔ ask feedback on the editor (pause, confirm, etc.) @done(24-08-07 07:36) - env - export Electron ne fonctionne pas diff --git a/eslint.config.mjs b/eslint.config.mjs index 6e66fbf..0ef591e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,55 +1,73 @@ -import globals from "globals"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import js from "@eslint/js"; -import { FlatCompat } from "@eslint/eslintrc"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +import globals from 'globals' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import js from '@eslint/js' +import { FlatCompat } from '@eslint/eslintrc' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: js.configs.recommended, - allConfig: js.configs.all -}); - -export default [{ - ignores: ["**/node_modules", "**/dist", "**/out", "**/.gitignore"], -}, ...compat.extends( - "plugin:vue/vue3-recommended", - "eslint:recommended", - "@vue/eslint-config-typescript/recommended", - "@vue/eslint-config-prettier", -), { + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}) + +export default [ + { + ignores: ['**/node_modules', '**/dist', '**/out', '**/.gitignore'] + }, + ...compat.extends( + 'plugin:vue/vue3-recommended', + 'eslint:recommended', + '@vue/eslint-config-typescript/recommended', + '@vue/eslint-config-prettier' + ), + { + files: ['**/src/**/*.ts', '**/src/**/*.vue'], + + rules: { + 'no-console': ['error'] + } + }, + { languageOptions: { - globals: { - ...globals.browser, - ...globals.commonjs, - ...globals.node, - ...vue.environments["setup-compiler-macros"]["setup-compiler-macros"], - }, + globals: { + ...globals.browser, + ...globals.commonjs, + ...globals.node + // ...vue.environments["setup-compiler-macros"]["setup-compiler-macros"], + } }, rules: { - "@typescript-eslint/ban-ts-comment": ["error", { - "ts-ignore": "allow-with-description", - }], + '@typescript-eslint/ban-ts-comment': [ + 'error', + { + 'ts-ignore': 'allow-with-description' + } + ], - "@typescript-eslint/explicit-module-boundary-types": "off", + '@typescript-eslint/explicit-module-boundary-types': 'off', - "@typescript-eslint/no-empty-function": ["error", { - allow: ["arrowFunctions"], - }], + '@typescript-eslint/no-empty-function': [ + 'error', + { + allow: ['arrowFunctions'] + } + ], - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-var-requires": "off", - "vue/require-default-prop": "off", - "vue/multi-word-component-names": "off", - }, -}, { - files: ["**/*.js"], + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-var-requires': 'off', + 'vue/require-default-prop': 'off', + 'vue/multi-word-component-names': 'off' + } + }, + { + files: ['**/*.js'], rules: { - "@typescript-eslint/explicit-function-return-type": "off", - }, -}]; \ No newline at end of file + '@typescript-eslint/explicit-function-return-type': 'off' + } + } +] diff --git a/package.json b/package.json index ce6cb9c..3fefd43 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "packageManager": "pnpm@9.5.0", "scripts": { "format": "prettier --write .", - "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix", + "lint": "eslint .", "typecheck:node": "tsc --noEmit -p tsconfig.json --composite false", "typecheck:web": "vue-tsc --noEmit -p tsconfig.json --composite false", "typecheck": "npm run typecheck:node && npm run typecheck:web", diff --git a/src/main.ts b/src/main.ts index 6746a9e..7a7d03c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,7 +2,7 @@ import { app, shell, BrowserWindow, dialog, autoUpdater } from 'electron' import { join } from 'path' import { platform } from 'os' import { electronApp, optimizer, is } from '@electron-toolkit/utils' -// @ts-expect-error +// @ts-expect-error asset import icon from '../assets/icon.png?asset' import { registerIPCHandlers } from './main/handlers' import { usePlugins } from '@@/plugins' @@ -12,20 +12,20 @@ import { Tray, Menu, nativeImage } from 'electron' import { readFile, writeFile, mkdir } from 'fs/promises' import { getFinalPlugins } from '@main/utils' import { SavedFile } from '@@/model' -import { handleActionExecute, handleConditionExecute } from '@main/handler-func' -import { logger } from '@@/logger' +import { handleActionExecute } from '@main/handler-func' +import { useLogger } from '@@/logger' import * as Sentry from '@sentry/electron/main' import { assetsPath } from '@main/paths' -// disable asar throughout the app - const isLinux = platform() === 'linux' let tray -logger.info('app.isPackaged', app.isPackaged) -logger.info('process.env.TEST', process.env.TEST) -logger.info('process.env.WINEHOMEDIR', process.env.WINEHOMEDIR) -logger.info('isLinux', isLinux) +const { logger, setMainWindow } = useLogger() + +logger().info('app.isPackaged', app.isPackaged) +logger().info('process.env.TEST', process.env.TEST) +logger().info('process.env.WINEHOMEDIR', process.env.WINEHOMEDIR) +logger().info('isLinux', isLinux) const isWine = platform() === 'win32' && 'WINEHOMEDIR' in process.env @@ -37,9 +37,7 @@ if (app.isPackaged && process.env.TEST !== 'true' && !isWine) { } const imagePath = join('./assets', 'icon.png') -let isQuiting = false - -console.log('imagePath', imagePath) +// let isQuiting = false if (!isLinux && process.env.TEST !== 'true' && require('electron-squirrel-startup')) app.quit() @@ -61,6 +59,8 @@ function createWindow(): void { } }) + setMainWindow(mainWindow) + if (is.dev) { mainWindow.webContents.openDevTools() } @@ -75,7 +75,7 @@ function createWindow(): void { mainWindow.hide() }) - mainWindow.on('close', function (event) { + mainWindow.on('close', function () { app.quit() }) @@ -110,9 +110,9 @@ app.whenReady().then(async () => { }) autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => { - logger.info('releaseNotes', releaseNotes) - logger.info('releaseName', releaseName) - logger.info('event', event) + logger().info('releaseNotes', releaseNotes) + logger().info('releaseName', releaseName) + logger().info('event', event) const dialogOpts: Electron.MessageBoxOptions = { type: 'info', buttons: ['Restart', 'Later'], @@ -127,25 +127,25 @@ app.whenReady().then(async () => { }) autoUpdater.on('error', (message) => { - logger.info('There was a problem updating the application') - logger.info(message) + logger().info('There was a problem updating the application') + logger().info(message) }) autoUpdater.on('update-available', () => { - logger.info('Found update') + logger().info('Found update') }) autoUpdater.on('update-not-available', () => { - logger.info('No update available') + logger().info('No update available') }) autoUpdater.on('checking-for-update', (info: any) => { - logger.info('checking-for-update', info) + logger().info('checking-for-update', info) }) - logger.info('app ready') + logger().info('app ready') autoUpdater.checkForUpdates() - logger.info('autoUpdater.getFeedURL()', autoUpdater.getFeedURL()) + logger().info('autoUpdater.getFeedURL()', autoUpdater.getFeedURL()) // Set app user model id for windows electronApp.setAppUserModelId('com.cyn') @@ -220,11 +220,11 @@ exec "${process.execPath}" "$@" const { values } = parseArgs(config) - logger.info('values', values) + logger().info('values', values) // exit if values are passed if (Object.keys(values).length > 0) { - logger.info('Processing graph...') + logger().info('Processing graph...') const { action, project, output } = values @@ -232,7 +232,7 @@ exec "${process.execPath}" "$@" const rawData = await readFile(project, 'utf8') const data = JSON.parse(rawData) as SavedFile - logger.info('data', data) + logger().info('data', data) const { canvas, variables } = data const { blocks: nodes } = canvas @@ -245,22 +245,22 @@ exec "${process.execPath}" "$@" steps: {}, context: {}, onNodeEnter: (node) => { - logger.info('onNodeEnter', node.uid) + logger().info('onNodeEnter', node.uid) }, onNodeExit: (node) => { - logger.info('onNodeExit', node.uid) + logger().info('onNodeExit', node.uid) }, - onExecuteItem: (node, params, steps) => { + onExecuteItem: (node, params/* , steps */) => { /* if (node.type === 'condition') { return handleConditionExecute(node.origin.nodeId, node.origin.pluginId, params, { send: (data) => { - logger.info('send', data) + logger().info('send', data) } }) } else */ if (node.type === 'action') { return handleActionExecute(node.origin.nodeId, node.origin.pluginId, params, mainWindow, { send: (data) => { - logger.info('send', data) + logger().info('send', data) } }) } else { @@ -296,7 +296,7 @@ exec "${process.execPath}" "$@" label: 'Exit', type: 'normal', click: () => { - isQuiting = true + // isQuiting = true app.quit() } } diff --git a/src/main/api.ts b/src/main/api.ts index 7325624..7bb3638 100644 --- a/src/main/api.ts +++ b/src/main/api.ts @@ -2,9 +2,11 @@ import { BrowserWindow } from 'electron' import { klona } from 'klona' import { toRaw } from 'vue' -import { RendererPluginDefinition } from '@cyn/plugin-core' import type { Tagged } from 'type-fest' +import { ILogObjMeta } from 'tslog' +import { useLogger } from '@@/logger' +// eslint-disable-next-line @typescript-eslint/no-unused-vars type Event = { type: TYPE; data: DATA } type EndEvent = { type: 'end'; data: DATA } @@ -15,6 +17,11 @@ export type IpcDefinition = { { message: string; buttons?: { title: string; value: string }[] }, EndEvent<{ answer: string }> ] + 'log:message': [ + // input + ILogObjMeta, + EndEvent + ] } export type RendererChannels = keyof IpcDefinition @@ -44,6 +51,7 @@ export type ListenerMain = ( ) => Promise export const usePluginAPI = (browserWindow: BrowserWindow) => { + const { logger } = useLogger() /** * Send an order */ @@ -93,8 +101,8 @@ export const usePluginAPI = (browserWindow: BrowserWindow) => { try { browserWindow.webContents.send(channel, message) } catch (e) { - console.error(e) - console.error(channel, message) + logger().error(e) + logger().error(channel, message) } }) } diff --git a/src/main/handler-func.ts b/src/main/handler-func.ts index 12b90a6..ba84766 100644 --- a/src/main/handler-func.ts +++ b/src/main/handler-func.ts @@ -12,9 +12,8 @@ import { randomBytes } from 'node:crypto' import { mkdir } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { HandleListenerSendFn } from './handlers' import { assetsPath, unpackPath } from './paths' -import { logger } from '@@/logger' +import { useLogger } from '@@/logger' import { BrowserWindow } from 'electron' import { usePluginAPI } from './api' @@ -47,9 +46,10 @@ export const handleConditionExecute = async ( nodeId: string, pluginId: string, params: any, - { send }: { send: HandleListenerSendFn<'condition:execute'> } + // { send }: { send: HandleListenerSendFn<'condition:execute'> } ): Promise> => { const { plugins } = usePlugins() + const { logger } = useLogger() const node = plugins.value .find((plugin) => plugin.id === pluginId) @@ -78,13 +78,13 @@ export const handleConditionExecute = async ( const value = await node.runner({ inputs: resolvedInputs, log: (...args) => { - logger.info(`[${node.node.name}]`, ...args) + logger().info(`[${node.node.name}]`, ...args) }, meta: { definition: '' }, setMeta: () => { - logger.info('set meta defined here') + logger().info('set meta defined here') }, cwd: tmp }) @@ -93,7 +93,7 @@ export const handleConditionExecute = async ( value } } catch (e) { - logger.error('e', e) + logger().error('e', e) return { result: { ipcError: e @@ -114,9 +114,10 @@ export const handleActionExecute = async ( pluginId: string, params: any, mainWindow: BrowserWindow | undefined, - { send }: { send: HandleListenerSendFn<'action:execute'> } + // { send }: { send: HandleListenerSendFn<'action:execute'> } ): Promise> => { const { plugins } = usePlugins() + const { logger } = useLogger() const node = plugins.value .find((plugin) => plugin.id === pluginId) @@ -141,21 +142,19 @@ export const handleActionExecute = async ( const resolvedInputs = params // await resolveActionInputs(params, node.node, steps) - logger.info('resolvedInputs', resolvedInputs) + logger().info('resolvedInputs', resolvedInputs) const _assetsPath = await assetsPath() const _unpackPath = await unpackPath() const outputs: Record = {} - console.log('mainWindow', mainWindow) - const api = usePluginAPI(mainWindow) await node.runner({ inputs: resolvedInputs, log: (...args) => { - logger.info(`[${node.node.name}]`, ...args) + logger().info(`[${node.node.name}]`, ...args) }, setOutput: (key, value) => { outputs[key] = value @@ -164,7 +163,7 @@ export const handleActionExecute = async ( definition: '' }, setMeta: () => { - logger.info('set meta defined here') + logger().info('set meta defined here') }, cwd: tmp, paths: { @@ -177,7 +176,7 @@ export const handleActionExecute = async ( outputs } } catch (e) { - logger.error('[action:execute] e', e) + logger().error('[action:execute] e', e) return { result: { ipcError: e diff --git a/src/main/handlers.ts b/src/main/handlers.ts index d4171da..95fcf95 100644 --- a/src/main/handlers.ts +++ b/src/main/handlers.ts @@ -1,26 +1,11 @@ import { Channels, Data, Events, Message } from '@@/apis' import { BrowserWindow, app, dialog, ipcMain } from 'electron' -import { usePlugins } from '@@/plugins' -import { - ActionRunner, - ConditionRunner, - Condition, - InputsDefinition, - Action -} from '../shared/libs/plugin-core' import { getFinalPlugins } from './utils' -import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' -import { randomBytes } from 'node:crypto' import { mkdir, writeFile, readFile, access } from 'node:fs/promises' import { presets } from './presets/list' -import { isRequired } from '@@/validation' import { handleActionExecute, handleConditionExecute } from './handler-func' -import { logger } from '@@/logger' - -function sleep(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)) -} +import { useLogger } from '@@/logger' export type HandleListenerSendFn = (events: Events) => void @@ -30,6 +15,8 @@ export type HandleListener = ( ) => Promise export const useAPI = () => { + const { logger } = useLogger() + const handle = (channel: KEY, listener: HandleListener) => { return ipcMain.on(channel, (event, message: Message) => { const { data, requestId } = message @@ -37,7 +24,7 @@ export const useAPI = () => { // logger.info('received data', data) const send: HandleListenerSendFn = (events) => { - logger.debug('sending', events, 'to', requestId) + logger().debug('sending', events, 'to', requestId) return event.sender.send(requestId, events) } @@ -55,20 +42,21 @@ export const useAPI = () => { export const registerIPCHandlers = () => { const { handle } = useAPI() + const { logger } = useLogger() - logger.info('registering ipc handlers') + logger().info('registering ipc handlers') handle('dialog:showOpenDialog', async (event, { value, send }) => { const slash = (await import('slash')).default - // logger.info('event', event) - logger.info('value', value) - logger.info('dialog:showOpenDialog') + // logger().info('event', event) + logger().info('value', value) + logger().info('dialog:showOpenDialog') const mainWindow = BrowserWindow.fromWebContents(event.sender) if (!mainWindow) { - console.error('mainWindow not found') + logger().error('mainWindow not found') return } @@ -84,9 +72,11 @@ export const registerIPCHandlers = () => { }) handle('fs:read', async (event, { value, send }) => { + const { logger } = useLogger() + // logger.info('event', event) - logger.info('value', value) - logger.info('fs:read') + logger().info('value', value) + logger().info('fs:read') try { const data = await readFile(value.path, 'utf-8') @@ -98,7 +88,7 @@ export const registerIPCHandlers = () => { } }) } catch (e) { - console.error('e', e) + logger().error('e', e) send({ type: 'end', data: { @@ -111,9 +101,10 @@ export const registerIPCHandlers = () => { }) handle('fs:write', async (event, { value, send }) => { + const { logger } = useLogger() // logger.info('event', event) - logger.info('value', value) - logger.info('fs:read') + logger().info('value', value) + logger().info('fs:read') await writeFile(value.path, value.content, 'utf-8') @@ -126,14 +117,16 @@ export const registerIPCHandlers = () => { }) handle('dialog:showSaveDialog', async (event, { value, send }) => { + const { logger } = useLogger() + // logger.info('event', event) - logger.info('value', value) - logger.info('dialog:showSaveDialog') + logger().info('value', value) + logger().info('dialog:showSaveDialog') const mainWindow = BrowserWindow.fromWebContents(event.sender) if (!mainWindow) { - console.error('mainWindow not found') + logger().error('mainWindow not found') return } @@ -180,12 +173,12 @@ export const registerIPCHandlers = () => { }) }) - handle('condition:execute', async (_, { send, value }) => { + handle('condition:execute', async (_, { value }) => { const { nodeId, params, pluginId } = value - await handleConditionExecute(nodeId, pluginId, params, { + await handleConditionExecute(nodeId, pluginId, params/* , { send, - }) + } */) }) handle('action:execute', async (event, { send, value }) => { @@ -193,11 +186,9 @@ export const registerIPCHandlers = () => { const mainWindow = BrowserWindow.fromWebContents(event.sender) - const result = await handleActionExecute(nodeId, pluginId, params, mainWindow, { - send, - }) + const result = await handleActionExecute(nodeId, pluginId, params, mainWindow) - // @ts-expect-error + // @ts-expect-error rrr await send({ data: result, type: 'end' @@ -228,7 +219,7 @@ export const registerIPCHandlers = () => { try { content = await readFile(filesPath, 'utf8') } catch (e) { - console.error('e', e) + logger().error('e', e) } const json = JSON.parse(content) diff --git a/src/preload.ts b/src/preload.ts index a209fb3..0b04c3c 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -3,8 +3,7 @@ import { electronAPI } from '@electron-toolkit/preload' import { version } from '../package.json' // Custom APIs for renderer -const api = { -} +const api = {} // TODO: unify window and contextBridge @@ -16,18 +15,17 @@ if (process.contextIsolated) { contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) contextBridge.exposeInMainWorld('version', version) - contextBridge.exposeInMainWorld("isPackaged", process.env.NODE_ENV !== "development") - contextBridge.exposeInMainWorld("isTest", process.env.TEST === 'true') + contextBridge.exposeInMainWorld('isPackaged', process.env.NODE_ENV !== 'development') + contextBridge.exposeInMainWorld('isTest', process.env.TEST === 'true') + // eslint-disable-next-line no-console console.log('process.env.NODE_ENV', process.env.NODE_ENV) // contextBridge.exposeInMainWorld('_dirname', __dirname) - } catch (error) { - console.error(error) - } + } catch (error) {} } else { window.electron = electronAPI window.api = api window.version = version - window.isPackaged = process.env.NODE_ENV !== "development" + window.isPackaged = process.env.NODE_ENV !== 'development' window.isTest = process.env.TEST === 'true' // window.__dirname = __dirname } diff --git a/src/renderer.ts b/src/renderer.ts index 8e97e4c..714acd0 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -1,3 +1 @@ import './renderer/main' - -console.log('renderer') diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 5266d07..6fd57ef 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -62,7 +62,8 @@ - -