generated from tailored/app-template
	init
This commit is contained in:
		@@ -1,11 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "name": "Node.js 22 Development Environment",
 | 
					 | 
				
			||||||
  "image": "mcr.microsoft.com/devcontainers/javascript-node:22",
 | 
					 | 
				
			||||||
  "settings": {
 | 
					 | 
				
			||||||
    "terminal.integrated.defaultProfile.linux": "/bin/bash"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "extensions": [
 | 
					 | 
				
			||||||
    "dbaeumer.vscode-eslint"
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  "postCreateCommand": "npm install -g @kevisual/envision-cli@latest && npm install"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,14 @@
 | 
				
			|||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dist
 | 
					dist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.config.json5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apps.config.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					deploy.tar.gz
 | 
				
			||||||
 | 
					cache-file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/apps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logs
 | 
				
			||||||
							
								
								
									
										2
									
								
								.npmrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.npmrc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
 | 
				
			||||||
 | 
					//registry.npmjs.org/:_authToken=${NPM_TOKEN}
 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
# app-template
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`/system/lib/app.js` 包函的模块是 `QueryRouterServer` 和 `Page` 和 `useConfigKey`
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
import { build } from 'esbuild';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
build({
 | 
					 | 
				
			||||||
  entryPoints: ['src/index.ts'],
 | 
					 | 
				
			||||||
  bundle: true,
 | 
					 | 
				
			||||||
  outfile: 'dist/index.js',
 | 
					 | 
				
			||||||
  platform: 'browser',
 | 
					 | 
				
			||||||
  target: 'esnext',
 | 
					 | 
				
			||||||
  sourcemap: false,
 | 
					 | 
				
			||||||
  format: 'esm',
 | 
					 | 
				
			||||||
}).catch(() => process.exit(1));
 | 
					 | 
				
			||||||
							
								
								
									
										31
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								index.html
									
									
									
									
									
								
							@@ -1,31 +0,0 @@
 | 
				
			|||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html lang="en">
 | 
					 | 
				
			||||||
<meta charset="UTF-8">
 | 
					 | 
				
			||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
					 | 
				
			||||||
<title>AI Apps</title>
 | 
					 | 
				
			||||||
<link rel="stylesheet" href="./src/assets/index.css">
 | 
					 | 
				
			||||||
<style>
 | 
					 | 
				
			||||||
  html,
 | 
					 | 
				
			||||||
  body {
 | 
					 | 
				
			||||||
    margin: 0;
 | 
					 | 
				
			||||||
    padding: 0;
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    height: 100%;
 | 
					 | 
				
			||||||
    overflow: hidden;
 | 
					 | 
				
			||||||
    font-size: 16px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  #ai-root {
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    height: 100%;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
<script src="/system/lib/app.js"></script>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
  <div id="ai-root"></div>
 | 
					 | 
				
			||||||
  <div id="ai-bot-root"></div>
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
<script src="./src/main.ts" type="module"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
							
								
								
									
										73
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								package.json
									
									
									
									
									
								
							@@ -1,48 +1,59 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "app-template",
 | 
					  "name": "@kevisual/ai-center",
 | 
				
			||||||
  "version": "0.0.1",
 | 
					  "version": "0.0.1",
 | 
				
			||||||
  "description": "",
 | 
					  "description": "",
 | 
				
			||||||
  "main": "index.js",
 | 
					  "main": "index.js",
 | 
				
			||||||
  "basename": "/me/app/",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "dev": "vite",
 | 
					    "watch": "rollup -c rollup.config.mjs -w",
 | 
				
			||||||
    "dev:web": "cross-env WEB_DEV=true vite --mode web",
 | 
					    "build": "rollup -c rollup.config.mjs",
 | 
				
			||||||
    "build": "vite build",
 | 
					    "dev": "cross-env NODE_ENV=development nodemon --delay 2.5 -e js,cjs,mjs --exec node dist/app.mjs",
 | 
				
			||||||
    "esbuild": "node esbuild.config.mjs",
 | 
					    "test": "tsx  test/**/*.ts",
 | 
				
			||||||
    "preview": "vite preview",
 | 
					    "dev:watch": "cross-env NODE_ENV=development concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ",
 | 
				
			||||||
    "prepub": "envision switchOrg user",
 | 
					    "clean": "rm -rf dist",
 | 
				
			||||||
    "pub": "envision deploy ./dist -k app-template -v 0.0.1"
 | 
					    "prepub": "envision switch root",
 | 
				
			||||||
  },
 | 
					    "pub": "npm run build && envision pack -p -u"
 | 
				
			||||||
  "stackblitz": {
 | 
					 | 
				
			||||||
    "startCommand": "npm dev:web"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "keywords": [],
 | 
					  "keywords": [],
 | 
				
			||||||
  "author": "abearxiong <xiongxiao@xiongxiao.me>",
 | 
					  "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
 | 
				
			||||||
  "license": "MIT",
 | 
					  "license": "MIT",
 | 
				
			||||||
 | 
					  "packageManager": "pnpm@10.7.1",
 | 
				
			||||||
  "type": "module",
 | 
					  "type": "module",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@floating-ui/dom": "^1.6.13",
 | 
					    "@kevisual/code-center-module": "0.0.18",
 | 
				
			||||||
    "@kevisual/query": "0.0.7-alpha.3",
 | 
					    "@kevisual/mark": "0.0.7",
 | 
				
			||||||
    "@kevisual/system-lib": "^0.0.10",
 | 
					    "@kevisual/router": "0.0.10",
 | 
				
			||||||
    "@kevisual/system-ui": "^0.0.3",
 | 
					    "cookie": "^1.0.2",
 | 
				
			||||||
    "dayjs": "^1.11.13",
 | 
					    "dayjs": "^1.11.13",
 | 
				
			||||||
    "lodash-es": "^4.17.21",
 | 
					    "formidable": "^3.5.2",
 | 
				
			||||||
    "react-dom": "^19.0.0",
 | 
					    "json5": "^2.2.3",
 | 
				
			||||||
    "zustand": "^5.0.3"
 | 
					    "lodash-es": "^4.17.21"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@kevisual/router": "0.0.6-alpha-5",
 | 
					 | 
				
			||||||
    "@kevisual/store": "0.0.1-alpha.10",
 | 
					 | 
				
			||||||
    "@kevisual/types": "^0.0.6",
 | 
					    "@kevisual/types": "^0.0.6",
 | 
				
			||||||
    "@tailwindcss/vite": "^4.0.9",
 | 
					    "@kevisual/use-config": "^1.0.10",
 | 
				
			||||||
    "@types/react": "^19.0.8",
 | 
					    "@rollup/plugin-alias": "^5.1.1",
 | 
				
			||||||
    "@types/react-dom": "^19.0.3",
 | 
					    "@rollup/plugin-commonjs": "^28.0.3",
 | 
				
			||||||
    "@vitejs/plugin-basic-ssl": "^1.2.0",
 | 
					    "@rollup/plugin-json": "^6.1.0",
 | 
				
			||||||
    "@vitejs/plugin-react": "^4.3.4",
 | 
					    "@rollup/plugin-node-resolve": "^16.0.1",
 | 
				
			||||||
 | 
					    "@rollup/plugin-replace": "^6.0.2",
 | 
				
			||||||
 | 
					    "@rollup/plugin-typescript": "^12.1.2",
 | 
				
			||||||
 | 
					    "@types/crypto-js": "^4.2.2",
 | 
				
			||||||
 | 
					    "@types/formidable": "^3.4.5",
 | 
				
			||||||
 | 
					    "@types/lodash-es": "^4.17.12",
 | 
				
			||||||
 | 
					    "@types/node": "^22.14.0",
 | 
				
			||||||
 | 
					    "concurrently": "^9.1.2",
 | 
				
			||||||
    "cross-env": "^7.0.3",
 | 
					    "cross-env": "^7.0.3",
 | 
				
			||||||
    "esbuild": "^0.25.0",
 | 
					    "jsrepo": "^1.45.3",
 | 
				
			||||||
    "react": "^19.0.0",
 | 
					    "nodemon": "^3.1.9",
 | 
				
			||||||
    "tailwindcss": "^4.0.9",
 | 
					    "pm2": "^6.0.5",
 | 
				
			||||||
    "vite": "^6.1.0"
 | 
					    "rimraf": "^6.0.1",
 | 
				
			||||||
 | 
					    "rollup": "^4.39.0",
 | 
				
			||||||
 | 
					    "rollup-plugin-copy": "^3.5.0",
 | 
				
			||||||
 | 
					    "rollup-plugin-dts": "^6.2.1",
 | 
				
			||||||
 | 
					    "rollup-plugin-esbuild": "^6.2.1",
 | 
				
			||||||
 | 
					    "sequelize": "^6.37.7",
 | 
				
			||||||
 | 
					    "tape": "^5.9.0",
 | 
				
			||||||
 | 
					    "tsx": "^4.19.3",
 | 
				
			||||||
 | 
					    "typescript": "^5.8.2"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										6279
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6279
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										75
									
								
								rollup.config.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								rollup.config.mjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					import resolve from '@rollup/plugin-node-resolve';
 | 
				
			||||||
 | 
					import commonjs from '@rollup/plugin-commonjs';
 | 
				
			||||||
 | 
					import json from '@rollup/plugin-json';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					import esbuild from 'rollup-plugin-esbuild';
 | 
				
			||||||
 | 
					import alias from '@rollup/plugin-alias';
 | 
				
			||||||
 | 
					import replace from '@rollup/plugin-replace';
 | 
				
			||||||
 | 
					import pkgs from './package.json' with {type: 'json'};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isDev = process.env.NODE_ENV === 'development';
 | 
				
			||||||
 | 
					const input = isDev ? './src/dev.ts' : './src/index.ts';
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @type {import('rollup').RollupOptions}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const config = {
 | 
				
			||||||
 | 
					  input,
 | 
				
			||||||
 | 
					  output: {
 | 
				
			||||||
 | 
					    dir: './dist',
 | 
				
			||||||
 | 
					    entryFileNames: 'app.mjs',
 | 
				
			||||||
 | 
					    chunkFileNames: '[name]-[hash].mjs',
 | 
				
			||||||
 | 
					    format: 'esm',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  plugins: [
 | 
				
			||||||
 | 
					    replace({
 | 
				
			||||||
 | 
					      preventAssignment: true, // 防止意外赋值
 | 
				
			||||||
 | 
					      DEV_SERVER: JSON.stringify(isDev), // 替换 process.env.NODE_ENV
 | 
				
			||||||
 | 
					      VERSION: JSON.stringify(pkgs.version),
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					    alias({
 | 
				
			||||||
 | 
					      // only esbuild needs to be configured
 | 
				
			||||||
 | 
					      entries: [
 | 
				
			||||||
 | 
					        { find: '@', replacement: path.resolve('src') }, // 配置 @ 为 src 目录
 | 
				
			||||||
 | 
					        { find: 'http', replacement: 'node:http' },
 | 
				
			||||||
 | 
					        { find: 'https', replacement: 'node:https' },
 | 
				
			||||||
 | 
					        { find: 'fs', replacement: 'node:fs' },
 | 
				
			||||||
 | 
					        { find: 'path', replacement: 'node:path' },
 | 
				
			||||||
 | 
					        { find: 'crypto', replacement: 'node:crypto' },
 | 
				
			||||||
 | 
					        { find: 'zlib', replacement: 'node:zlib' },
 | 
				
			||||||
 | 
					        { find: 'stream', replacement: 'node:stream' },
 | 
				
			||||||
 | 
					        { find: 'net', replacement: 'node:net' },
 | 
				
			||||||
 | 
					        { find: 'tty', replacement: 'node:tty' },
 | 
				
			||||||
 | 
					        { find: 'tls', replacement: 'node:tls' },
 | 
				
			||||||
 | 
					        { find: 'buffer', replacement: 'node:buffer' },
 | 
				
			||||||
 | 
					        { find: 'timers', replacement: 'node:timers' },
 | 
				
			||||||
 | 
					        // { find: 'string_decoder', replacement: 'node:string_decoder' },
 | 
				
			||||||
 | 
					        { find: 'dns', replacement: 'node:dns' },
 | 
				
			||||||
 | 
					        { find: 'domain', replacement: 'node:domain' },
 | 
				
			||||||
 | 
					        { find: 'os', replacement: 'node:os' },
 | 
				
			||||||
 | 
					        { find: 'events', replacement: 'node:events' },
 | 
				
			||||||
 | 
					        { find: 'url', replacement: 'node:url' },
 | 
				
			||||||
 | 
					        { find: 'assert', replacement: 'node:assert' },
 | 
				
			||||||
 | 
					        { find: 'util', replacement: 'node:util' },
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					    resolve({
 | 
				
			||||||
 | 
					      preferBuiltins: true, // 强制优先使用内置模块
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					    commonjs(),
 | 
				
			||||||
 | 
					    esbuild({
 | 
				
			||||||
 | 
					      target: 'node22', //
 | 
				
			||||||
 | 
					      minify: false, // 启用代码压缩
 | 
				
			||||||
 | 
					      tsconfig: 'tsconfig.json',
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					    json(),
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  external: [
 | 
				
			||||||
 | 
					    /@kevisual\/router(\/.*)?/, //, // 路由
 | 
				
			||||||
 | 
					    /@kevisual\/use-config(\/.*)?/, //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 'sequelize', // 数据库 orm
 | 
				
			||||||
 | 
					    // 'ioredis', // redis
 | 
				
			||||||
 | 
					    // 'pg', // pg
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export default config;
 | 
				
			||||||
@@ -1,94 +0,0 @@
 | 
				
			|||||||
// import { nanoid } from 'nanoid';
 | 
					 | 
				
			||||||
import { RefObject, SyntheticEvent } from 'react';
 | 
					 | 
				
			||||||
const randomId = () => {
 | 
					 | 
				
			||||||
  return crypto.getRandomValues(new Uint32Array(1))[0].toString(16);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
const loadChidren = (element: any, children: any[]) => {
 | 
					 | 
				
			||||||
  children.forEach((child) => {
 | 
					 | 
				
			||||||
    if (typeof child === 'boolean') {
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (typeof child === 'function') {
 | 
					 | 
				
			||||||
      // console.log('child', child);
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (typeof child === 'undefined') {
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // console.log('child', child);
 | 
					 | 
				
			||||||
    element.appendChild(typeof child === 'string' ? document.createTextNode(child) : child);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
// 在项目中定义 h 函数
 | 
					 | 
				
			||||||
export function h(type: string | Function, props: any, ...children: any[]): HTMLElement {
 | 
					 | 
				
			||||||
  if (typeof type === 'function') {
 | 
					 | 
				
			||||||
    const element = type(props);
 | 
					 | 
				
			||||||
    loadChidren(element, children);
 | 
					 | 
				
			||||||
    return element;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  const element = document.createElement(type);
 | 
					 | 
				
			||||||
  const filterKeys = ['onLoad', 'onUnload', 'key'];
 | 
					 | 
				
			||||||
  const key = props?.key || randomId();
 | 
					 | 
				
			||||||
  Object.entries(props || {}).forEach(([key, value]) => {
 | 
					 | 
				
			||||||
    if (filterKeys.includes(key)) {
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (key === 'className') {
 | 
					 | 
				
			||||||
      element.setAttribute('class', value as string);
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (key.startsWith('on')) {
 | 
					 | 
				
			||||||
      element.addEventListener(key.slice(2).toLowerCase(), value as EventListener);
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (key === 'ref' && value) {
 | 
					 | 
				
			||||||
      (value as any).current = element;
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (typeof value === 'object') {
 | 
					 | 
				
			||||||
      console.log('error', element, type, value);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      element.setAttribute(key, value as string);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  const onLoad = props?.onLoad;
 | 
					 | 
				
			||||||
  const checkConnect = () => {
 | 
					 | 
				
			||||||
    if (element.isConnected) {
 | 
					 | 
				
			||||||
      onLoad?.({ el: element, key, _props: props });
 | 
					 | 
				
			||||||
      // console.log('onLoad', element, key);
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  setTimeout(() => {
 | 
					 | 
				
			||||||
    const res = checkConnect();
 | 
					 | 
				
			||||||
    if (!res) {
 | 
					 | 
				
			||||||
      setTimeout(() => {}, 1000);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }, 20);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  loadChidren(element, children);
 | 
					 | 
				
			||||||
  return element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
declare global {
 | 
					 | 
				
			||||||
  namespace JSX {
 | 
					 | 
				
			||||||
    // type Element = HTMLElement; // 将 JSX.Element 设置为 HTMLElement
 | 
					 | 
				
			||||||
    interface Element extends HTMLElement {
 | 
					 | 
				
			||||||
      class?: string;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  namespace React {
 | 
					 | 
				
			||||||
    interface FormEvent<T = Element> extends SyntheticEvent<T> {
 | 
					 | 
				
			||||||
      target: EventTarget & (T extends HTMLInputElement ? HTMLInputElement : T);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const useRef = <T = HTMLDivElement>(initialValue: T | null = null): RefObject<T | null> => {
 | 
					 | 
				
			||||||
  return { current: initialValue };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const useEffect = (callback: () => void) => {
 | 
					 | 
				
			||||||
  setTimeout(callback, 0);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
import { createRoot } from 'react-dom/client';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const ReactApp = () => {
 | 
					 | 
				
			||||||
  const root = createRoot(document.getElementById('app')!);
 | 
					 | 
				
			||||||
  root.render(<div>Hello, World!</div>);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
import type { Page } from '@kevisual/store/page';
 | 
					 | 
				
			||||||
import type { QueryRouterServer } from '@kevisual/router';
 | 
					 | 
				
			||||||
export const page = useContextKey('page', () => {
 | 
					 | 
				
			||||||
  return new window.Page({
 | 
					 | 
				
			||||||
    basename: '',
 | 
					 | 
				
			||||||
  }) as unknown as Page;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const app = useContextKey('app', () => {
 | 
					 | 
				
			||||||
  console.error('app not found');
 | 
					 | 
				
			||||||
  return null as unknown as QueryRouterServer;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,39 +0,0 @@
 | 
				
			|||||||
import { page, app } from './app.ts';
 | 
					 | 
				
			||||||
export const render = ({ renderRoot }) => {
 | 
					 | 
				
			||||||
  renderRoot.innerHTML = `
 | 
					 | 
				
			||||||
    <h1>Hello, World!</h1>
 | 
					 | 
				
			||||||
  `;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (page) {
 | 
					 | 
				
			||||||
  page.addPage('/app-template', 'home');
 | 
					 | 
				
			||||||
  page.subscribe('home', () => {
 | 
					 | 
				
			||||||
    render({
 | 
					 | 
				
			||||||
      renderRoot: document.getElementById('ai-root'),
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (app) {
 | 
					 | 
				
			||||||
  app
 | 
					 | 
				
			||||||
    .route({
 | 
					 | 
				
			||||||
      path: 'app-template',
 | 
					 | 
				
			||||||
      key: 'render',
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .define(async (ctx) => {
 | 
					 | 
				
			||||||
      let { renderRoot } = ctx.query;
 | 
					 | 
				
			||||||
      if (!renderRoot) {
 | 
					 | 
				
			||||||
        ctx.throw(404, 'renderRoot is required');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (typeof renderRoot === 'string') {
 | 
					 | 
				
			||||||
        renderRoot = document.querySelector(renderRoot);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (!renderRoot) {
 | 
					 | 
				
			||||||
        ctx.throw(404, 'renderRoot not found');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      render({
 | 
					 | 
				
			||||||
        renderRoot,
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .addTo(app);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,85 +0,0 @@
 | 
				
			|||||||
import { create } from 'zustand';
 | 
					 | 
				
			||||||
import { query } from '@/modules/query';
 | 
					 | 
				
			||||||
type Store = {
 | 
					 | 
				
			||||||
  list: any[];
 | 
					 | 
				
			||||||
  setList: (list: any[]) => void;
 | 
					 | 
				
			||||||
  data: any;
 | 
					 | 
				
			||||||
  setData: (data: any) => void;
 | 
					 | 
				
			||||||
  loading: boolean;
 | 
					 | 
				
			||||||
  setLoading: (loading: boolean) => void;
 | 
					 | 
				
			||||||
  formData: any;
 | 
					 | 
				
			||||||
  setFormData: (data: any) => void;
 | 
					 | 
				
			||||||
  getList: () => Promise<any>;
 | 
					 | 
				
			||||||
  init: () => Promise<void>;
 | 
					 | 
				
			||||||
  getData: (id: number) => Promise<any>;
 | 
					 | 
				
			||||||
  updateData: (data: any, opts?: { refresh?: boolean }) => Promise<any>;
 | 
					 | 
				
			||||||
  deleteData: (id: number, opts?: { refresh?: boolean }) => Promise<any>;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
export const useStore = create<Store>((set, get) => ({
 | 
					 | 
				
			||||||
  list: [],
 | 
					 | 
				
			||||||
  setList: (list) => set({ list }),
 | 
					 | 
				
			||||||
  data: null,
 | 
					 | 
				
			||||||
  setData: (data) => set({ data }),
 | 
					 | 
				
			||||||
  loading: false,
 | 
					 | 
				
			||||||
  setLoading: (loading) => set({ loading }),
 | 
					 | 
				
			||||||
  formData: null,
 | 
					 | 
				
			||||||
  setFormData: (formData) => set({ formData }),
 | 
					 | 
				
			||||||
  getList: async () => {
 | 
					 | 
				
			||||||
    set({ loading: true });
 | 
					 | 
				
			||||||
    const res = await query.post({ path: 'posts', key: 'list' });
 | 
					 | 
				
			||||||
    set({ loading: false });
 | 
					 | 
				
			||||||
    if (res.code === 200) {
 | 
					 | 
				
			||||||
      set({ list: res.data });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return res;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  init: async () => {
 | 
					 | 
				
			||||||
    await get().getList();
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  getData: async (id) => {
 | 
					 | 
				
			||||||
    set({ loading: true });
 | 
					 | 
				
			||||||
    const res = await query.post({
 | 
					 | 
				
			||||||
      path: 'posts',
 | 
					 | 
				
			||||||
      key: 'get',
 | 
					 | 
				
			||||||
      id,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    set({ loading: false });
 | 
					 | 
				
			||||||
    if (res.code === 200) {
 | 
					 | 
				
			||||||
      const data = res.data;
 | 
					 | 
				
			||||||
      set({ data });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return res;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  updateData: async (data, opts = { refresh: true }) => {
 | 
					 | 
				
			||||||
    set({ loading: true });
 | 
					 | 
				
			||||||
    const res = await query.post({
 | 
					 | 
				
			||||||
      path: 'posts',
 | 
					 | 
				
			||||||
      key: 'update',
 | 
					 | 
				
			||||||
      data,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    set({ loading: false });
 | 
					 | 
				
			||||||
    if (res.code === 200) {
 | 
					 | 
				
			||||||
      set({ data: res.data });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (opts.refresh) {
 | 
					 | 
				
			||||||
      await get().getList();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return res;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  deleteData: async (id, opts = { refresh: true }) => {
 | 
					 | 
				
			||||||
    set({ loading: true });
 | 
					 | 
				
			||||||
    const res = await query.post({
 | 
					 | 
				
			||||||
      path: 'posts',
 | 
					 | 
				
			||||||
      key: 'delete',
 | 
					 | 
				
			||||||
      id,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    set({ loading: false });
 | 
					 | 
				
			||||||
    if (res.code === 200) {
 | 
					 | 
				
			||||||
      set({ data: null });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (opts.refresh) {
 | 
					 | 
				
			||||||
      await get().getList();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return res;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
}));
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								src/app.ts
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/app.ts
									
									
									
									
									
								
							@@ -1,12 +1,8 @@
 | 
				
			|||||||
import type { Page } from '@kevisual/store/page';
 | 
					import { App } from '@kevisual/router';
 | 
				
			||||||
import type { QueryRouterServer } from '@kevisual/router';
 | 
					import { useContextKey } from '@kevisual/use-config/context';
 | 
				
			||||||
import { basename } from './modules/basename';
 | 
					
 | 
				
			||||||
export const page = useContextKey('page', () => {
 | 
					const init = () => {
 | 
				
			||||||
  return new window.Page({
 | 
					  return new App();
 | 
				
			||||||
    basename,
 | 
					};
 | 
				
			||||||
  }) as unknown as Page;
 | 
					
 | 
				
			||||||
});
 | 
					export const app = useContextKey('app', init);
 | 
				
			||||||
export const app = useContextKey('app', () => {
 | 
					 | 
				
			||||||
  console.error('app not found');
 | 
					 | 
				
			||||||
  return null as unknown as QueryRouterServer;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
@import "tailwindcss";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@layer components {
 | 
					 | 
				
			||||||
  .test-loading {
 | 
					 | 
				
			||||||
    @apply w-20 h-20 bg-gray-300 rounded-full animate-spin;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ai-bot-root {
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
  height: 100%;
 | 
					 | 
				
			||||||
  position: fixed;
 | 
					 | 
				
			||||||
  top: 0;
 | 
					 | 
				
			||||||
  left: -100px;
 | 
					 | 
				
			||||||
  z-index: 9999;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								src/demo-route.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/demo-route.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					import { app } from './app.ts';
 | 
				
			||||||
 | 
					import { useConfig } from '@kevisual/use-config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app
 | 
				
			||||||
 | 
					  .route({
 | 
				
			||||||
 | 
					    path: 'demo',
 | 
				
			||||||
 | 
					    key: 'demo',
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .define(async (ctx) => {
 | 
				
			||||||
 | 
					    ctx.body = '123';
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .addTo(app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const config = useConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log('run demo: http://localhost:' + config.port + '/api/router?path=demo&key=demo');
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/dev.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/dev.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					import { useConfig } from '@kevisual/use-config';
 | 
				
			||||||
 | 
					import { app } from './index.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const config = useConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.listen(config.port, () => {
 | 
				
			||||||
 | 
					  console.log(`server is running at http://localhost:${config.port}`);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import { app } from './app.ts';
 | 
				
			||||||
 | 
					import './demo-route.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { app };
 | 
				
			||||||
							
								
								
									
										54
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/main.ts
									
									
									
									
									
								
							@@ -1,48 +1,10 @@
 | 
				
			|||||||
import { page, app } from './app.ts';
 | 
					// 单应用实例启动
 | 
				
			||||||
import { basename } from './modules/basename.ts';
 | 
					 | 
				
			||||||
export const render = ({ renderRoot }) => {
 | 
					 | 
				
			||||||
  renderRoot.innerHTML = `
 | 
					 | 
				
			||||||
    <h1>Hello, World!</h1>
 | 
					 | 
				
			||||||
  `;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
console.log('basename', basename, page, app);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (page) {
 | 
					import { useConfig } from '@kevisual/use-config';
 | 
				
			||||||
  page.addPage('/app-template', 'home');
 | 
					import { app } from './index.ts';
 | 
				
			||||||
  page.subscribe('home', () => {
 | 
					 | 
				
			||||||
    render({
 | 
					 | 
				
			||||||
      renderRoot: document.getElementById('ai-root'),
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  page.addPage('', 'index');
 | 
					 | 
				
			||||||
  page.subscribe('index', () => {
 | 
					 | 
				
			||||||
    const root = document.getElementById('ai-root') as HTMLElement;
 | 
					 | 
				
			||||||
    root.innerHTML = `
 | 
					 | 
				
			||||||
      <h1>Hello, World!</h1>
 | 
					 | 
				
			||||||
    `;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (app) {
 | 
					const config = useConfig();
 | 
				
			||||||
  app
 | 
					
 | 
				
			||||||
    .route({
 | 
					app.listen(config.port, () => {
 | 
				
			||||||
      path: 'app-template',
 | 
					  console.log(`server is running at http://localhost:${config.port}`);
 | 
				
			||||||
      key: 'render',
 | 
					});
 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .define(async (ctx) => {
 | 
					 | 
				
			||||||
      let { renderRoot } = ctx.query;
 | 
					 | 
				
			||||||
      if (!renderRoot) {
 | 
					 | 
				
			||||||
        ctx.throw(404, 'renderRoot is required');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (typeof renderRoot === 'string') {
 | 
					 | 
				
			||||||
        renderRoot = document.querySelector(renderRoot);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (!renderRoot) {
 | 
					 | 
				
			||||||
        ctx.throw(404, 'renderRoot not found');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      render({
 | 
					 | 
				
			||||||
        renderRoot,
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .addTo(app);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
// @ts-ignore
 | 
					 | 
				
			||||||
export const basename = DEV_SERVER ? '/' : BASE_NAME;
 | 
					 | 
				
			||||||
							
								
								
									
										9
									
								
								src/modules/mark.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/modules/mark.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import { Mark, markModelInit } from '@kevisual/mark';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { Mark, markModelInit };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const init = () => {
 | 
				
			||||||
 | 
					  markModelInit({
 | 
				
			||||||
 | 
					    tableName: '',
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
import { message } from '@kevisual/system-ui/dist/message';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export { message };
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
import { QueryClient } from '@kevisual/query';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const query = new QueryClient();
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								src/modules/sequelize.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/modules/sequelize.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					export { sequelize, redis } from '@kevisual/code-center-module';
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/modules/user.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/modules/user.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import { sequelize, User, UserInit, Org, OrgInit } from '@kevisual/code-center-module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { sequelize, User, UserInit, Org, OrgInit };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const init = () => {
 | 
				
			||||||
 | 
					  UserInit();
 | 
				
			||||||
 | 
					  OrgInit();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					init();
 | 
				
			||||||
							
								
								
									
										78
									
								
								src/routes/ai-manager/models/provider.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/routes/ai-manager/models/provider.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					import { sequelize } from '@kevisual/code-center-module';
 | 
				
			||||||
 | 
					import { DataTypes, Model } from 'sequelize';
 | 
				
			||||||
 | 
					export type Provider = Partial<InstanceType<typeof ProviderModel>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ModelItem = {
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 模型
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  model: string;
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 提供者
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  provider: string;
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 配置, 自有配置
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  config: Record<string, any>;
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 标题
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  title: string;
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 描述
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  description: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export type ProviderData = {
 | 
				
			||||||
 | 
					  models: ModelItem[];
 | 
				
			||||||
 | 
					  config: Record<string, any>; // 共享配置
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export class ProviderModel extends Model {
 | 
				
			||||||
 | 
					  declare id: string;
 | 
				
			||||||
 | 
					  declare title: string;
 | 
				
			||||||
 | 
					  declare description: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare config: Record<string, any>;
 | 
				
			||||||
 | 
					  declare data: Record<string, any>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare uid: string;
 | 
				
			||||||
 | 
					  declare createdAt: Date;
 | 
				
			||||||
 | 
					  declare updatedAt: Date;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ProviderModel.init(
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    id: {
 | 
				
			||||||
 | 
					      type: DataTypes.UUID,
 | 
				
			||||||
 | 
					      primaryKey: true,
 | 
				
			||||||
 | 
					      defaultValue: DataTypes.UUIDV4,
 | 
				
			||||||
 | 
					      comment: 'id',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    title: {
 | 
				
			||||||
 | 
					      type: DataTypes.TEXT,
 | 
				
			||||||
 | 
					      defaultValue: '',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    description: {
 | 
				
			||||||
 | 
					      type: DataTypes.TEXT,
 | 
				
			||||||
 | 
					      defaultValue: '',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    config: {
 | 
				
			||||||
 | 
					      type: DataTypes.JSON,
 | 
				
			||||||
 | 
					      defaultValue: {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    data: {
 | 
				
			||||||
 | 
					      type: DataTypes.JSON,
 | 
				
			||||||
 | 
					      defaultValue: {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    uid: {
 | 
				
			||||||
 | 
					      type: DataTypes.UUID,
 | 
				
			||||||
 | 
					      allowNull: true,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    sequelize,
 | 
				
			||||||
 | 
					    tableName: 'kv_provider',
 | 
				
			||||||
 | 
					    paranoid: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
@@ -1,43 +1,33 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "compilerOptions": {
 | 
					  "compilerOptions": {
 | 
				
			||||||
    "jsx": "react",
 | 
					    "module": "nodenext",
 | 
				
			||||||
    "target": "ES2020",
 | 
					    "target": "esnext",
 | 
				
			||||||
    "useDefineForClassFields": true,
 | 
					    "noImplicitAny": false,
 | 
				
			||||||
    "lib": [
 | 
					    "outDir": "./dist",
 | 
				
			||||||
      "ES2020",
 | 
					    "sourceMap": false,
 | 
				
			||||||
      "DOM",
 | 
					    "allowJs": true,
 | 
				
			||||||
      "DOM.Iterable"
 | 
					    "newLine": "LF",
 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "module": "ESNext",
 | 
					 | 
				
			||||||
    "skipLibCheck": true,
 | 
					 | 
				
			||||||
    /* Bundler mode */
 | 
					 | 
				
			||||||
    "moduleResolution": "bundler",
 | 
					 | 
				
			||||||
    "allowImportingTsExtensions": true,
 | 
					 | 
				
			||||||
    "isolatedModules": true,
 | 
					 | 
				
			||||||
    "moduleDetection": "force",
 | 
					 | 
				
			||||||
    "noEmit": true,
 | 
					 | 
				
			||||||
    // "jsxFragmentFactory": "Fragment",
 | 
					 | 
				
			||||||
    // "jsxFactory": "h",
 | 
					 | 
				
			||||||
    "baseUrl": "./",
 | 
					    "baseUrl": "./",
 | 
				
			||||||
    "typeRoots": [
 | 
					    "typeRoots": [
 | 
				
			||||||
      "node_modules/@types",
 | 
					      "node_modules/@types",
 | 
				
			||||||
      "node_modules/@kevisual/types",
 | 
					      "node_modules/@kevisual/types"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "declaration": true,
 | 
				
			||||||
 | 
					    "noEmit": false,
 | 
				
			||||||
 | 
					    "allowImportingTsExtensions": true,
 | 
				
			||||||
 | 
					    "emitDeclarationOnly": true,
 | 
				
			||||||
 | 
					    "moduleResolution": "NodeNext",
 | 
				
			||||||
 | 
					    "experimentalDecorators": true,
 | 
				
			||||||
 | 
					    "emitDecoratorMetadata": true,
 | 
				
			||||||
 | 
					    "esModuleInterop": true,
 | 
				
			||||||
    "paths": {
 | 
					    "paths": {
 | 
				
			||||||
      "@/*": [
 | 
					      "@/*": [
 | 
				
			||||||
        "src/*"
 | 
					        "src/*"
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    }
 | 
				
			||||||
    /* Linting */
 | 
					 | 
				
			||||||
    "strict": true,
 | 
					 | 
				
			||||||
    "noImplicitAny": false,
 | 
					 | 
				
			||||||
    "noUnusedLocals": false,
 | 
					 | 
				
			||||||
    "noUnusedParameters": false,
 | 
					 | 
				
			||||||
    "noFallthroughCasesInSwitch": true
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "include": [
 | 
					  "include": [
 | 
				
			||||||
    "src",
 | 
					    "src/**/*.ts",
 | 
				
			||||||
    "typings.d.ts",
 | 
					  ],
 | 
				
			||||||
    "snippets"
 | 
					  "exclude": [],
 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,55 +0,0 @@
 | 
				
			|||||||
import { defineConfig } from 'vite';
 | 
					 | 
				
			||||||
import basicSsl from '@vitejs/plugin-basic-ssl';
 | 
					 | 
				
			||||||
// import react from '@vitejs/plugin-react';
 | 
					 | 
				
			||||||
import dayjs from 'dayjs';
 | 
					 | 
				
			||||||
import path from 'path';
 | 
					 | 
				
			||||||
import tailwindcss from '@tailwindcss/vite'
 | 
					 | 
				
			||||||
import pkgs from './package.json' with { type: 'json' };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const isDev = process.env.NODE_ENV === 'development';
 | 
					 | 
				
			||||||
const isWebDev = process.env.WEB_DEV === 'true';
 | 
					 | 
				
			||||||
const BUILD_TIME = dayjs().format('YYYY-MM-DD HH:mm:ss');
 | 
					 | 
				
			||||||
const basename = pkgs.basename;
 | 
					 | 
				
			||||||
let plugins = [tailwindcss(),];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (!isWebDev) {
 | 
					 | 
				
			||||||
  // 在bolt的web开发环境下不需要ssl
 | 
					 | 
				
			||||||
  plugins.push(basicSsl());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineConfig({
 | 
					 | 
				
			||||||
  plugins: plugins,
 | 
					 | 
				
			||||||
  resolve: {
 | 
					 | 
				
			||||||
    alias: {
 | 
					 | 
				
			||||||
      '@': path.resolve(__dirname, './src'),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  base: isDev ? '/' : basename,
 | 
					 | 
				
			||||||
  define: {
 | 
					 | 
				
			||||||
    DEV_SERVER: JSON.stringify(isDev),
 | 
					 | 
				
			||||||
    BUILD_TIME: JSON.stringify(BUILD_TIME),
 | 
					 | 
				
			||||||
    BASE_NAME: JSON.stringify(basename),
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  optimizeDeps: {
 | 
					 | 
				
			||||||
    exclude: ['react'], // 排除 react 和 react-dom 以避免打包
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // esbuild: {
 | 
					 | 
				
			||||||
  //   jsxFactory: 'h',
 | 
					 | 
				
			||||||
  //   jsxFragment: 'Fragment',
 | 
					 | 
				
			||||||
  // },
 | 
					 | 
				
			||||||
  server: {
 | 
					 | 
				
			||||||
    port: 6025,
 | 
					 | 
				
			||||||
    host: '0.0.0.0',
 | 
					 | 
				
			||||||
    proxy: {
 | 
					 | 
				
			||||||
      '/api': {
 | 
					 | 
				
			||||||
        target: 'https://kevisual.xiongxiao.me',
 | 
					 | 
				
			||||||
        changeOrigin: true,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      '/system/lib': {
 | 
					 | 
				
			||||||
        target: 'https://kevisual.xiongxiao.me',
 | 
					 | 
				
			||||||
        changeOrigin: true,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user