initiate ziya
This commit is contained in:
commit
13166b7a19
34 changed files with 27043 additions and 0 deletions
124
.config/.eslintrc.json
Normal file
124
.config/.eslintrc.json
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
// .eslintrc.json
|
||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"MAIN_WINDOW_VITE_DEV_SERVER_URL": "readonly",
|
||||||
|
"MAIN_WINDOW_VITE_NAME": "readonly"
|
||||||
|
},
|
||||||
|
// 'positive' dirs in .vscode/settings.json
|
||||||
|
// "ignorePatterns" → .eslintignore
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:import/recommended",
|
||||||
|
"plugin:import/electron",
|
||||||
|
"plugin:import/typescript",
|
||||||
|
"plugin:vue/vue3-recommended",
|
||||||
|
"prettier"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module",
|
||||||
|
"extraFileExtensions": [
|
||||||
|
".vue"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"import/resolver": {
|
||||||
|
"typescript": { // REF www.npmjs.com/package/eslint-import-resolver-typescript#configuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.vue"
|
||||||
|
],
|
||||||
|
"parser": "vue-eslint-parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"vue/html-closing-bracket-spacing": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"selfClosingTag": "never"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"src/*.d.ts"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"semi": [
|
||||||
|
"warn",
|
||||||
|
"never",
|
||||||
|
{
|
||||||
|
"beforeStatementContinuationChars": "always"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-tabs": "error",
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"max-statements-per-line": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"max": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"space-before-function-paren": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"anonymous": "always",
|
||||||
|
"named": "never",
|
||||||
|
"asyncArrow": "always"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// tolerate but do not enforce comma-dangle
|
||||||
|
"comma-dangle": "off",
|
||||||
|
// up to 3 blank lines is semantics for me
|
||||||
|
"no-multiple-empty-lines": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"max": 3,
|
||||||
|
"maxBOF": 1,
|
||||||
|
"maxEOF": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// not having to worry about danling commas is a blessing (either way)
|
||||||
|
"@typescript-eslint/comma-dangle": "off",
|
||||||
|
// handier for testing
|
||||||
|
"import/no-named-as-default-member": "off",
|
||||||
|
// writing the type can be clarifying at times, thus permit
|
||||||
|
"@typescript-eslint/no-inferrable-types": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"argsIgnorePattern": "^_"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
32
.config/eslint.mjs
Normal file
32
.config/eslint.mjs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
import withNuxt from "../.nuxt/eslint.config.mjs";
|
||||||
|
|
||||||
|
export default withNuxt([{
|
||||||
|
files: ["**/*.vue", "**/*.js", "**/*.ts", "**/*.mjs"],
|
||||||
|
rules: {
|
||||||
|
"camelcase": ["error", { properties: "never", ignoreDestructuring: true }],
|
||||||
|
"no-console": ["error", { allow: ["info", "warn"] }],
|
||||||
|
"sort-imports": ["error", { ignoreDeclarationSort: true }],
|
||||||
|
"@stylistic/indent": ["error", 2, { SwitchCase: 1 }],
|
||||||
|
"@stylistic/linebreak-style": ["error", process.platform === "win32" ? "windows" : "unix"],
|
||||||
|
"@stylistic/quotes": ["error", "double"],
|
||||||
|
"@stylistic/semi": ["error", "always"],
|
||||||
|
"@stylistic/no-extra-semi": "error",
|
||||||
|
"@stylistic/comma-dangle": ["error", "never"],
|
||||||
|
"@stylistic/space-before-function-paren": ["error", "always"],
|
||||||
|
"@stylistic/multiline-ternary": ["error", "never"],
|
||||||
|
"@stylistic/member-delimiter-style": ["error", { multiline: { delimiter: "semi" }, singleline: { delimiter: "comma" } }],
|
||||||
|
"@stylistic/arrow-spacing": ["error", { before: true, after: true }],
|
||||||
|
"@stylistic/brace-style": ["error", "stroustrup", { allowSingleLine: true }],
|
||||||
|
"@stylistic/no-multi-spaces": "error",
|
||||||
|
"@stylistic/space-before-blocks": "error",
|
||||||
|
"@stylistic/no-trailing-spaces": "error",
|
||||||
|
"nuxt/prefer-import-meta": "error",
|
||||||
|
"vue/first-attribute-linebreak": ["error", { singleline: "ignore", multiline: "ignore" }],
|
||||||
|
"vue/max-attributes-per-line": ["error", { singleline: 100 }],
|
||||||
|
"vue/singleline-html-element-content-newline": ["off"],
|
||||||
|
"vue/no-multiple-template-root": ["off"],
|
||||||
|
"vue/html-closing-bracket-spacing": ["error", { selfClosingTag: "always" }],
|
||||||
|
"vue/html-indent": ["error", 2],
|
||||||
|
"vue/multiline-html-element-content-newline": ["error", { ignores: [] }]
|
||||||
|
}
|
||||||
|
}]);
|
||||||
96
.config/forge.ts
Normal file
96
.config/forge.ts
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
import { MakerDeb } from "@electron-forge/maker-deb";
|
||||||
|
import { MakerDMG } from "@electron-forge/maker-dmg";
|
||||||
|
import { MakerSquirrel } from "@electron-forge/maker-squirrel";
|
||||||
|
import { MakerZIP } from "@electron-forge/maker-zip";
|
||||||
|
import { AutoUnpackNativesPlugin } from "@electron-forge/plugin-auto-unpack-natives";
|
||||||
|
import { FusesPlugin } from "@electron-forge/plugin-fuses";
|
||||||
|
import { VitePlugin } from "@electron-forge/plugin-vite";
|
||||||
|
import { PublisherGithub } from "@electron-forge/publisher-github";
|
||||||
|
import type { ForgeConfig } from "@electron-forge/shared-types";
|
||||||
|
import { FuseV1Options, FuseVersion } from "@electron/fuses";
|
||||||
|
import setLanguages from "electron-packager-languages";
|
||||||
|
import packageJSON from "../package.json";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
packagerConfig: {
|
||||||
|
name: packageJSON.name,
|
||||||
|
appBundleId: "com.bismillahdao.ziya",
|
||||||
|
appCategoryType: "public.app-category.utilities",
|
||||||
|
appCopyright: `Copyright (C) ${new Date().getFullYear()} ${packageJSON.author.name}`,
|
||||||
|
icon: "public/favicon",
|
||||||
|
asar: {
|
||||||
|
unpack: "**/node_modules/{sharp,@img}/**/*"
|
||||||
|
},
|
||||||
|
osxSign: {},
|
||||||
|
ignore: [
|
||||||
|
/^\/(?!node_modules|package\.json|.vite)/
|
||||||
|
],
|
||||||
|
afterCopy: [setLanguages(["en", "en-US", "en-GB"])]
|
||||||
|
},
|
||||||
|
rebuildConfig: {
|
||||||
|
onlyModules: ["sharp"],
|
||||||
|
force: true
|
||||||
|
},
|
||||||
|
makers: [
|
||||||
|
new MakerZIP({}),
|
||||||
|
// Windows
|
||||||
|
new MakerSquirrel({
|
||||||
|
usePackageJson: true,
|
||||||
|
iconUrl: "https://raw.githubusercontent.com/rizilab/ziya/main/public/favicon.ico",
|
||||||
|
setupIcon: "public/favicon.ico"
|
||||||
|
}),
|
||||||
|
// macOS
|
||||||
|
new MakerDMG({
|
||||||
|
overwrite: true,
|
||||||
|
format: "ULFO",
|
||||||
|
icon: "public/favicon.icns"
|
||||||
|
}),
|
||||||
|
// Linux
|
||||||
|
new MakerDeb({
|
||||||
|
options: {
|
||||||
|
categories: ["Utility"],
|
||||||
|
icon: "public/favicon.png"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
new VitePlugin({
|
||||||
|
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
|
||||||
|
// If you are familiar with Vite configuration, it will look really familiar.
|
||||||
|
build: [
|
||||||
|
{
|
||||||
|
entry: "electron/main.ts",
|
||||||
|
config: ".config/vite.forge.ts",
|
||||||
|
target: "main"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entry: "electron/preload.ts",
|
||||||
|
config: ".config/vite.forge.ts",
|
||||||
|
target: "preload"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
renderer: [] // Nuxt app is generated no need to specify renderer
|
||||||
|
}),
|
||||||
|
// Fuses are used to enable/disable various Electron functionality
|
||||||
|
// at package time, before code signing the application
|
||||||
|
new FusesPlugin({
|
||||||
|
version: FuseVersion.V1,
|
||||||
|
[FuseV1Options.RunAsNode]: false,
|
||||||
|
[FuseV1Options.EnableCookieEncryption]: true,
|
||||||
|
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
|
||||||
|
[FuseV1Options.EnableNodeCliInspectArguments]: false,
|
||||||
|
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
|
||||||
|
[FuseV1Options.OnlyLoadAppFromAsar]: true
|
||||||
|
}),
|
||||||
|
new AutoUnpackNativesPlugin({})
|
||||||
|
],
|
||||||
|
publishers: [
|
||||||
|
new PublisherGithub({
|
||||||
|
repository: {
|
||||||
|
owner: "Rizary",
|
||||||
|
name: packageJSON.name
|
||||||
|
},
|
||||||
|
prerelease: true
|
||||||
|
})
|
||||||
|
]
|
||||||
|
} satisfies ForgeConfig;
|
||||||
76
.config/nuxt.ts
Normal file
76
.config/nuxt.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { APP } from "../app/utils/app";
|
||||||
|
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
modules: [
|
||||||
|
"@nuxt/ui",
|
||||||
|
"@nuxt/eslint",
|
||||||
|
"@pinia/nuxt"
|
||||||
|
],
|
||||||
|
ssr: false,
|
||||||
|
devtools: { enabled: true },
|
||||||
|
app: {
|
||||||
|
baseURL: "./",
|
||||||
|
cdnURL: "./",
|
||||||
|
head: {
|
||||||
|
title: APP.name,
|
||||||
|
meta: [
|
||||||
|
{ "http-equiv": "content-security-policy", "content": "script-src 'self' 'unsafe-inline'" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
css: [
|
||||||
|
"~/assets/css/ui.tailwind.css",
|
||||||
|
"~/assets/scss/app.scss"
|
||||||
|
],
|
||||||
|
router: {
|
||||||
|
options: {
|
||||||
|
hashMode: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colorMode: {
|
||||||
|
preference: "dark",
|
||||||
|
fallback: "dark",
|
||||||
|
storageKey: "nuxt-color-mode"
|
||||||
|
},
|
||||||
|
ui: {
|
||||||
|
colorMode: true,
|
||||||
|
fonts: false
|
||||||
|
},
|
||||||
|
future: { compatibilityVersion: 4 },
|
||||||
|
features: {
|
||||||
|
inlineStyles: false
|
||||||
|
},
|
||||||
|
experimental: {
|
||||||
|
typedPages: true,
|
||||||
|
payloadExtraction: false,
|
||||||
|
renderJsonPayloads: false
|
||||||
|
},
|
||||||
|
compatibilityDate: "2025-05-26",
|
||||||
|
vite: {
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
api: "modern-compiler",
|
||||||
|
silenceDeprecations: ["mixed-decls", "color-functions", "import", "global-builtin"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
postcss: {
|
||||||
|
plugins: {
|
||||||
|
"@tailwindcss/postcss": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
eslint: {
|
||||||
|
config: {
|
||||||
|
autoInit: false,
|
||||||
|
stylistic: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
provider: "iconify",
|
||||||
|
clientBundle: {
|
||||||
|
scan: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
16
.config/stylelint.json
Normal file
16
.config/stylelint.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"extends": "stylelint-config-standard-scss",
|
||||||
|
"rules": {
|
||||||
|
"length-zero-no-unit": true,
|
||||||
|
"rule-empty-line-before": ["always-multi-line", { "except": ["first-nested"] }],
|
||||||
|
"color-function-notation": ["modern", { "ignore": ["with-var-inside"] }],
|
||||||
|
"scss/double-slash-comment-empty-line-before": "never"
|
||||||
|
},
|
||||||
|
"ignoreFiles": [
|
||||||
|
"../node_modules/**/*",
|
||||||
|
"../.nuxt/**/*",
|
||||||
|
"../dist/**/*",
|
||||||
|
"../.output/**/*",
|
||||||
|
"../public/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
33
.config/vite.forge.ts
Normal file
33
.config/vite.forge.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { cp, mkdir } from "node:fs/promises";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { type Plugin, defineConfig } from "vite";
|
||||||
|
|
||||||
|
const copyNuxtOutput: Plugin = {
|
||||||
|
name: "copy-nuxt-output",
|
||||||
|
async closeBundle () {
|
||||||
|
const outputDir = fileURLToPath(new URL("../.output/public", import.meta.url));
|
||||||
|
const targetDir = fileURLToPath(new URL("../.vite/renderer", import.meta.url));
|
||||||
|
await mkdir(targetDir, { recursive: true });
|
||||||
|
await cp(outputDir, targetDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
publicDir: false,
|
||||||
|
plugins: [copyNuxtOutput],
|
||||||
|
build: {
|
||||||
|
emptyOutDir: false,
|
||||||
|
lib: {
|
||||||
|
entry: "electron/main.ts",
|
||||||
|
formats: ["cjs"]
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
entryFileNames: "[name].cjs"
|
||||||
|
},
|
||||||
|
external: [
|
||||||
|
"electron",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
24
.editorconfig
Normal file
24
.editorconfig
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
max_line_length = 200
|
||||||
|
|
||||||
|
// NOTE: has auto-save impact! always.
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{js,ts,vue,css,scss,sass,html}]
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{txt, md}]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
insert_final_newline = false
|
||||||
|
|
||||||
|
[*.{yml, json},.prettierrc]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
5
.eslintignore
Normal file
5
.eslintignore
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
node_modules/*
|
||||||
|
dist/*
|
||||||
|
|
||||||
|
# all hidden files, too!
|
||||||
|
.*/*
|
||||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
* text=auto eol=lf
|
||||||
94
.gitignore
vendored
Normal file
94
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# Webpack
|
||||||
|
.webpack/
|
||||||
|
|
||||||
|
# Vite
|
||||||
|
.vite/
|
||||||
|
|
||||||
|
# Electron-Forge
|
||||||
|
out/
|
||||||
|
|
||||||
|
.cursor/
|
||||||
3
.npmrc
Normal file
3
.npmrc
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
shamefully-hoist=true
|
||||||
|
strict-peer-dependencies=false
|
||||||
|
node-linker=hoisted
|
||||||
16
.prettierrc
Normal file
16
.prettierrc
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"semi": false,
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"plugins": [
|
||||||
|
"prettier-plugin-vue"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.vue",
|
||||||
|
"options": {
|
||||||
|
"parser": "vue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
9
.vscode/extensions.json
vendored
Normal file
9
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"syler.sass-indented",
|
||||||
|
"vue.volar",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"editorconfig.editorconfig",
|
||||||
|
"vitest.explorer"
|
||||||
|
]
|
||||||
|
}
|
||||||
59
.vscode/settings.json
vendored
Normal file
59
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"typescript",
|
||||||
|
"vue"
|
||||||
|
],
|
||||||
|
"eslint.useFlatConfig": true,
|
||||||
|
"eslint.options": {
|
||||||
|
"extensions": [
|
||||||
|
".js",
|
||||||
|
".ts",
|
||||||
|
".mts",
|
||||||
|
".vue"
|
||||||
|
],
|
||||||
|
"overrideConfigFile": ".config/eslint.mjs"
|
||||||
|
},
|
||||||
|
"eslint.workingDirectories": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"eslint.probe": [
|
||||||
|
"javascript",
|
||||||
|
"typescript",
|
||||||
|
"html",
|
||||||
|
"vue"
|
||||||
|
],
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"**/.vite": true,
|
||||||
|
"**/dist": true,
|
||||||
|
"**/build": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.defaultFormatter": "vscode.typescript-language-features",
|
||||||
|
"javascript.preferences.quoteStyle": "single"
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.defaultFormatter": "vscode.typescript-language-features",
|
||||||
|
"typescript.preferences.quoteStyle": "single"
|
||||||
|
},
|
||||||
|
"[vue]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[sass]": {
|
||||||
|
"editor.defaultFormatter": "syler.sass-indented",
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "vscode.json-language-features",
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"[jsonc]": {
|
||||||
|
"editor.defaultFormatter": "vscode.json-language-features",
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
}
|
||||||
196
README.md
Normal file
196
README.md
Normal file
|
|
@ -0,0 +1,196 @@
|
||||||
|
# Ziya Token Monitor
|
||||||
|
|
||||||
|
A modern Electron-based desktop application for monitoring Solana token creation, CEX findings, and developer balance source graphs. Built with React, Redux, and TypeScript.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
This project follows a modular architecture with three main packages:
|
||||||
|
|
||||||
|
### 📦 Packages
|
||||||
|
|
||||||
|
- **`@ziya/shared`** - Shared types, utilities, and domain models
|
||||||
|
- **`@ziya/frontend`** - React frontend with Redux state management
|
||||||
|
- **`@ziya/backend`** - Electron main process with Redis integration
|
||||||
|
|
||||||
|
### 🏗️ Tech Stack
|
||||||
|
|
||||||
|
- **Frontend**: React 18, Redux Toolkit, TypeScript, Styled Components, Vite
|
||||||
|
- **Backend**: Electron, Node.js, TypeScript, Redis (ioredis)
|
||||||
|
- **Shared**: TypeScript, Winston (logging)
|
||||||
|
- **Development**: Yarn Workspaces, ESLint, Prettier
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- 📊 **Real-time Dashboard** - Monitor token activity at a glance
|
||||||
|
- 🪙 **Token Management** - Track discovered tokens and their metadata
|
||||||
|
- 🕸️ **Graph Visualization** - Visualize connection graphs for developer relationships
|
||||||
|
- 📝 **Event Streaming** - Real-time events from the Rust backend via Redis
|
||||||
|
- 🌙 **Dark/Light Theme** - Modern UI with theme switching
|
||||||
|
- 🔔 **Notifications** - Real-time notifications for important events
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Node.js 16+
|
||||||
|
- Yarn (recommended)
|
||||||
|
- Redis server running on localhost:6379
|
||||||
|
- Rust backend (`muhafidh`) running and publishing events
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. **Clone and install dependencies**:
|
||||||
|
```bash
|
||||||
|
cd ziya
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Build shared module**:
|
||||||
|
```bash
|
||||||
|
yarn workspace @ziya/shared build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Start Development Server
|
||||||
|
```bash
|
||||||
|
# Start both frontend and backend in development mode
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Start the React frontend on `http://localhost:5173`
|
||||||
|
- Start the Electron backend in development mode
|
||||||
|
- Enable hot reload for both frontend and backend
|
||||||
|
|
||||||
|
### Individual Package Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Frontend only
|
||||||
|
yarn workspace @ziya/frontend start
|
||||||
|
|
||||||
|
# Backend only
|
||||||
|
yarn workspace @ziya/backend dev
|
||||||
|
|
||||||
|
# Shared module
|
||||||
|
yarn workspace @ziya/shared dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build all packages
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# Package the Electron app
|
||||||
|
yarn package
|
||||||
|
```
|
||||||
|
|
||||||
|
## Event Integration
|
||||||
|
|
||||||
|
The application listens for these Redis events from the `muhafidh` Rust backend:
|
||||||
|
|
||||||
|
### `token_cex_updated`
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mint": "string",
|
||||||
|
"name": "string",
|
||||||
|
"uri": "string",
|
||||||
|
"dev_name": "string",
|
||||||
|
"cex_name": "string",
|
||||||
|
"cex_address": "string",
|
||||||
|
"cex_updated_at": "string",
|
||||||
|
"node_count": "number",
|
||||||
|
"edge_count": "number",
|
||||||
|
"graph": {
|
||||||
|
"nodes": [...],
|
||||||
|
"edges": [...]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `max_depth_reached`
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mint": "string",
|
||||||
|
"name": "string",
|
||||||
|
"uri": "string",
|
||||||
|
"bonding_curve": "string",
|
||||||
|
"updated_at": "string",
|
||||||
|
"node_count": "number",
|
||||||
|
"edge_count": "number",
|
||||||
|
"graph": {
|
||||||
|
"nodes": [...],
|
||||||
|
"edges": [...]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Redis Configuration
|
||||||
|
Set environment variables:
|
||||||
|
```bash
|
||||||
|
REDIS_HOST=localhost
|
||||||
|
REDIS_PORT=6379
|
||||||
|
```
|
||||||
|
|
||||||
|
### Electron Configuration
|
||||||
|
The app uses secure defaults:
|
||||||
|
- Context isolation enabled
|
||||||
|
- Node integration disabled
|
||||||
|
- Preload script for secure IPC
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
ziya/
|
||||||
|
├── packages/
|
||||||
|
│ ├── shared/ # Shared types and utilities
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── types/ # TypeScript interfaces
|
||||||
|
│ │ │ └── utils/ # Shared utilities
|
||||||
|
│ │ └── package.json
|
||||||
|
│ ├── frontend/ # React frontend
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── components/ # React components
|
||||||
|
│ │ │ ├── pages/ # Page components
|
||||||
|
│ │ │ ├── store/ # Redux store and slices
|
||||||
|
│ │ │ ├── services/ # Frontend services
|
||||||
|
│ │ │ └── styles/ # Styled components
|
||||||
|
│ │ └── package.json
|
||||||
|
│ └── backend/ # Electron backend
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── services/ # Backend services
|
||||||
|
│ │ ├── main.ts # Electron main process
|
||||||
|
│ │ └── preload.ts # Preload script
|
||||||
|
│ └── package.json
|
||||||
|
├── package.json # Root workspace config
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
- `yarn dev` - Start development servers
|
||||||
|
- `yarn build` - Build all packages
|
||||||
|
- `yarn start` - Start production app
|
||||||
|
- `yarn package` - Package Electron app
|
||||||
|
- `yarn clean` - Clean all build artifacts
|
||||||
|
- `yarn lint` - Run linters
|
||||||
|
- `yarn test` - Run tests
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
- Electron app uses context isolation and disables node integration
|
||||||
|
- IPC communication uses secure preload scripts
|
||||||
|
- Redis connections use proper error handling and reconnection logic
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create a feature branch
|
||||||
|
3. Make your changes
|
||||||
|
4. Run tests and linting
|
||||||
|
5. Submit a pull request
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License - see LICENSE file for details.
|
||||||
42
app/app.vue
Normal file
42
app/app.vue
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<div class="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||||
|
<div class="max-w-md w-full bg-white rounded-lg shadow-lg p-8">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="text-3xl font-bold text-gray-900 mb-4">
|
||||||
|
Hello World! 👋
|
||||||
|
</h1>
|
||||||
|
<p class="text-gray-600 mb-6">
|
||||||
|
Welcome to Ziya - Your Vue + Nuxt + Electron App
|
||||||
|
</p>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<UButton
|
||||||
|
@click="count++"
|
||||||
|
color="primary"
|
||||||
|
size="lg"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
Click me! ({{ count }})
|
||||||
|
</UButton>
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
Built with Vue {{ vueVersion }}, Nuxt {{ nuxtVersion }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { version as vueVersion } from 'vue/package.json'
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
const nuxtVersion = '3.17.5' // From your package.json
|
||||||
|
|
||||||
|
// Page metadata
|
||||||
|
useHead({
|
||||||
|
title: 'Ziya - Hello World',
|
||||||
|
meta: [
|
||||||
|
{ name: 'description', content: 'One Stop Shop for your trading needs' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
43
app/assets/css/ui.tailwind.css
Normal file
43
app/assets/css/ui.tailwind.css
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* stylelint-disable scss/at-rule-no-unknown, custom-property-empty-line-before */
|
||||||
|
@import "tailwindcss";
|
||||||
|
@import "@nuxt/ui";
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
@custom-variant light (&:where(.light, .light *));
|
||||||
|
@custom-variant hover (&:hover);
|
||||||
|
|
||||||
|
@theme static {
|
||||||
|
--color-green-50: #ebfdf6;
|
||||||
|
--color-green-100: #d4f8eb;
|
||||||
|
--color-green-200: #a7f2d9;
|
||||||
|
--color-green-300: #6ae6c2;
|
||||||
|
--color-green-400: #00d1a6;
|
||||||
|
--color-green-500: #00ba91;
|
||||||
|
--color-green-600: #009775;
|
||||||
|
--color-green-700: #1B886D;
|
||||||
|
--color-green-800: #005f4a;
|
||||||
|
--color-green-900: #164c3d;
|
||||||
|
--color-green-950: #052c21;
|
||||||
|
|
||||||
|
|
||||||
|
--color-slate-50: #f9fafb;
|
||||||
|
--color-slate-100: #f3f4f6;
|
||||||
|
--color-slate-200: #e2e5e9;
|
||||||
|
--color-slate-300: #cdd5e1;
|
||||||
|
--color-slate-400: #92a1b7;
|
||||||
|
--color-slate-500: #63738a;
|
||||||
|
--color-slate-600: #44546b;
|
||||||
|
--color-slate-700: #354151;
|
||||||
|
--color-slate-800: #222830;
|
||||||
|
--color-slate-900: #15191e;
|
||||||
|
--color-slate-950: #06090E;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--ui-primary: var(--ui-color-primary-700);
|
||||||
|
--ui-secondary: var(--ui-color-secondary-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--ui-primary: var(--ui-color-primary-400);
|
||||||
|
--ui-secondary: var(--ui-color-secondary-300);
|
||||||
|
}
|
||||||
29
app/assets/scss/_main.scss
Normal file
29
app/assets/scss/_main.scss
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
scrollbar-width: auto;
|
||||||
|
scroll-behavior: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background-color: var(--ui-bg-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
height: 56px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 0 solid transparent;
|
||||||
|
background-clip: content-box;
|
||||||
|
background-color: var(--ui-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: var(--ui-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: var(--ui-primary);
|
||||||
|
color: var(--ui-bg-muted);
|
||||||
|
}
|
||||||
83
app/assets/scss/_transitions.scss
Normal file
83
app/assets/scss/_transitions.scss
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
.slide-enter-active,
|
||||||
|
.slide-leave-active,
|
||||||
|
.slide-right-enter-active,
|
||||||
|
.slide-right-leave-active,
|
||||||
|
.slide-left-enter-active,
|
||||||
|
.slide-left-leave-active {
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-enter-from,
|
||||||
|
.slide-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(0, -10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-right-enter-from,
|
||||||
|
.slide-right-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(10px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-enter-from,
|
||||||
|
.slide-left-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-10px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bounce-enter-active {
|
||||||
|
animation: bounce-in 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce-in {
|
||||||
|
0% { transform: scale(0);}
|
||||||
|
50% { transform: scale(1.25);}
|
||||||
|
100% {transform: scale(1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-move,
|
||||||
|
.list-enter-active,
|
||||||
|
.list-leave-active {
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-enter-from,
|
||||||
|
.list-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
width: 0%;
|
||||||
|
left: 50%;
|
||||||
|
top: 100%;
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $size in (200, 1000) {
|
||||||
|
.expand-#{$size} {
|
||||||
|
&-enter-active,
|
||||||
|
&-leave-active {
|
||||||
|
transition: max-height 0.3s ease-in-out, opacity 0.2s ease;
|
||||||
|
max-height: #{$size}px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-enter-from,
|
||||||
|
&-leave-to {
|
||||||
|
max-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
app/assets/scss/app.scss
Normal file
2
app/assets/scss/app.scss
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
@import "main";
|
||||||
|
@import "transitions";
|
||||||
13
app/layouts/default.vue
Normal file
13
app/layouts/default.vue
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<template>
|
||||||
|
<div class="min-h-screen">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// Default layout for the app
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Global styles can go here */
|
||||||
|
</style>
|
||||||
67
app/pages/index.vue
Normal file
67
app/pages/index.vue
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
<template>
|
||||||
|
<div class="container mx-auto px-4 py-8">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="text-4xl font-bold text-gray-900 mb-6">
|
||||||
|
🚀 Ziya Dashboard
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 max-w-4xl mx-auto">
|
||||||
|
<!-- Trading Card -->
|
||||||
|
<div class="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
|
||||||
|
<div class="text-blue-500 text-3xl mb-4">📈</div>
|
||||||
|
<h3 class="text-xl font-semibold mb-2">Trading</h3>
|
||||||
|
<p class="text-gray-600">Access your trading dashboard and monitor your portfolio</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Analytics Card -->
|
||||||
|
<div class="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
|
||||||
|
<div class="text-green-500 text-3xl mb-4">📊</div>
|
||||||
|
<h3 class="text-xl font-semibold mb-2">Analytics</h3>
|
||||||
|
<p class="text-gray-600">View detailed analytics and market insights</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Settings Card -->
|
||||||
|
<div class="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
|
||||||
|
<div class="text-purple-500 text-3xl mb-4">⚙️</div>
|
||||||
|
<h3 class="text-xl font-semibold mb-2">Settings</h3>
|
||||||
|
<p class="text-gray-600">Configure your preferences and account settings</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-8">
|
||||||
|
<UButton
|
||||||
|
@click="showWelcome = !showWelcome"
|
||||||
|
color="primary"
|
||||||
|
size="lg"
|
||||||
|
>
|
||||||
|
{{ showWelcome ? 'Hide' : 'Show' }} Welcome Message
|
||||||
|
</UButton>
|
||||||
|
|
||||||
|
<div v-if="showWelcome" class="mt-4 p-4 bg-blue-50 rounded-lg">
|
||||||
|
<p class="text-blue-800">
|
||||||
|
Welcome to your new Electron app! This is running on Nuxt {{ nuxtVersion }} with Vue {{ vueVersion }}.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { version as vueVersion } from 'vue/package.json'
|
||||||
|
|
||||||
|
const showWelcome = ref(false)
|
||||||
|
const nuxtVersion = '3.17.5'
|
||||||
|
|
||||||
|
// Page metadata
|
||||||
|
definePageMeta({
|
||||||
|
title: 'Dashboard'
|
||||||
|
})
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: 'Ziya - Dashboard',
|
||||||
|
meta: [
|
||||||
|
{ name: 'description', content: 'Ziya trading dashboard - One stop shop for your trading needs' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
4
app/utils/app.ts
Normal file
4
app/utils/app.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const APP = {
|
||||||
|
name: "ziya",
|
||||||
|
repository: "https://github.com/rizilab/ziya"
|
||||||
|
};
|
||||||
1
app/utils/electron.ts
Normal file
1
app/utils/electron.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export const useElectron = () => window.electron;
|
||||||
73
electron/main.ts
Normal file
73
electron/main.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { BrowserWindow, app, shell } from "electron";
|
||||||
|
import started from 'electron-squirrel-startup';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
||||||
|
if (started) {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const createWindow = () => {
|
||||||
|
// Create the browser window.
|
||||||
|
const mainWindow = new BrowserWindow({
|
||||||
|
minHeight: 800,
|
||||||
|
minWidth: 1080,
|
||||||
|
maxHeight: 1080,
|
||||||
|
maxWidth: 1920,
|
||||||
|
height: 1024,
|
||||||
|
width: 1280,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false,
|
||||||
|
contextIsolation: true,
|
||||||
|
preload: path.join(__dirname, 'preload.cjs'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.setMenuBarVisibility(false);
|
||||||
|
mainWindow.webContents.on("will-navigate", function (event, reqUrl) {
|
||||||
|
const requestedHost = new URL(reqUrl).host;
|
||||||
|
const currentHost = new URL(mainWindow.webContents.getURL()).host;
|
||||||
|
if (requestedHost && requestedHost != currentHost) {
|
||||||
|
event.preventDefault();
|
||||||
|
shell.openExternal(reqUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const isDev = process.env.NODE_ENV === "development";
|
||||||
|
// and load the index.html of the app.
|
||||||
|
if (isDev) {
|
||||||
|
mainWindow.setIcon(fileURLToPath(new URL("../../public/favicon.ico", import.meta.url)));
|
||||||
|
mainWindow.loadURL("http://localhost:3000");
|
||||||
|
mainWindow.webContents.openDevTools();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWindow.loadFile(path.join(__dirname, "../renderer/index.html"));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// This method will be called when Electron has finished
|
||||||
|
// initialization and is ready to create browser windows.
|
||||||
|
// Some APIs can only be used after this event occurs.
|
||||||
|
app.on('ready', createWindow);
|
||||||
|
|
||||||
|
// Quit when all windows are closed, except on macOS. There, it's common
|
||||||
|
// for applications and their menu bar to stay active until the user quits
|
||||||
|
// explicitly with Cmd + Q.
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
// On OS X it's common to re-create a window in the app when the
|
||||||
|
// dock icon is clicked and there are no other windows open.
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// In this file you can include the rest of your app's specific main process
|
||||||
|
// code. You can also put them in separate files and import them here.
|
||||||
9
electron/preload.ts
Normal file
9
electron/preload.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { contextBridge } from "electron";
|
||||||
|
|
||||||
|
// Expose protected methods that allow the renderer process to use
|
||||||
|
// the ipcRenderer without exposing the entire object
|
||||||
|
export const handlers = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld("electron", handlers);
|
||||||
10072
package-lock.json
generated
Normal file
10072
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
71
package.json
Normal file
71
package.json
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"name": "Ziya",
|
||||||
|
"productName": "Ziya",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "One Stop Shop for your trading needs",
|
||||||
|
"type": "module",
|
||||||
|
"main": ".vite/build/main.cjs",
|
||||||
|
"scripts": {
|
||||||
|
"start": "electron-forge start",
|
||||||
|
"dev": "concurrently \"pnpm run dev:nuxt\" \"pnpm run dev:electron\"",
|
||||||
|
"dev:nuxt": "nuxt dev --config-file .config/nuxt.config.ts",
|
||||||
|
"dev:electron": "cross-env NODE_ENV=development electron-forge start",
|
||||||
|
"build": "nuxt generate --config-file .config/nuxt.config.ts && electron-forge make",
|
||||||
|
"package": "electron-forge package",
|
||||||
|
"make": "electron-forge make",
|
||||||
|
"publish": "electron-forge publish",
|
||||||
|
"lint": "eslint --ext .ts,.tsx,.js,.vue --ignore-path .gitignore .",
|
||||||
|
"format": "prettier --write ."
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "rizary",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@electron-forge/cli": "^7.8.1",
|
||||||
|
"@electron-forge/maker-deb": "^7.8.1",
|
||||||
|
"@electron-forge/maker-dmg": "^7.8.1",
|
||||||
|
"@electron-forge/maker-rpm": "^7.8.1",
|
||||||
|
"@electron-forge/maker-squirrel": "^7.8.1",
|
||||||
|
"@electron-forge/maker-zip": "^7.8.1",
|
||||||
|
"@electron-forge/plugin-auto-unpack-natives": "^7.8.1",
|
||||||
|
"@electron-forge/plugin-fuses": "^7.8.1",
|
||||||
|
"@electron-forge/plugin-vite": "^7.8.1",
|
||||||
|
"@electron-forge/publisher-github": "^7.8.1",
|
||||||
|
"@electron/fuses": "^1.8.0",
|
||||||
|
"@nuxt/eslint": "^1.4.1",
|
||||||
|
"@nuxt/ui": "^3.1.3",
|
||||||
|
"@pinia/nuxt": "^0.11.1",
|
||||||
|
"@types/electron-squirrel-startup": "^1.0.2",
|
||||||
|
"@types/node": "^24.0.3",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||||
|
"@typescript-eslint/parser": "^5.62.0",
|
||||||
|
"changelogen": "^0.6.1",
|
||||||
|
"concurrently": "^9.1.2",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"electron": "36.5.0",
|
||||||
|
"electron-packager-languages": "^0.6.0",
|
||||||
|
"eslint": "^8.57.1",
|
||||||
|
"eslint-config-prettier": "^10.1.5",
|
||||||
|
"eslint-plugin-import": "^2.32.0",
|
||||||
|
"nuxt": "^3.17.5",
|
||||||
|
"pinia": "^3.0.3",
|
||||||
|
"prettier": "3.5.3",
|
||||||
|
"sass": "^1.89.2",
|
||||||
|
"stylelint": "^16.21.0",
|
||||||
|
"stylelint-config-standard-scss": "^15.0.1",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "~4.5.4",
|
||||||
|
"vite": "^5.4.19",
|
||||||
|
"vite-plugin-electron": "^0.29.0",
|
||||||
|
"vite-plugin-electron-renderer": "^0.14.6",
|
||||||
|
"vitest": "^3.2.4",
|
||||||
|
"vue-tsc": "^2.2.10"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"electron-squirrel-startup": "^1.0.1"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"forge": ".config/forge.ts"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac"
|
||||||
|
}
|
||||||
15723
pnpm-lock.yaml
generated
Normal file
15723
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load diff
12
pnpm-workspace.yaml
Normal file
12
pnpm-workspace.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
nodeLinker: hoisted
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- .
|
||||||
|
|
||||||
|
ignoredBuiltDependencies:
|
||||||
|
- '@parcel/watcher'
|
||||||
|
- esbuild
|
||||||
|
|
||||||
|
onlyBuiltDependencies:
|
||||||
|
- electron
|
||||||
|
- electron-winstaller
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
3
tsconfig.json
Normal file
3
tsconfig.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
||||||
11
types/electron.d.ts
vendored
Normal file
11
types/electron.d.ts
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import type { handlers } from "./../electron/preload";
|
||||||
|
|
||||||
|
type ElectronAPI = typeof handlers;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
electron: ElectronAPI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { };
|
||||||
1
types/forge.d.ts
vendored
Normal file
1
types/forge.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="@electron-forge/plugin-vite/forge-vite-env" />
|
||||||
Loading…
Add table
Reference in a new issue