feat: change env
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
import { useConfig } from '@kevisual/use-config';
 | 
			
		||||
import { useConfig } from '@kevisual/use-config/env';
 | 
			
		||||
import { useFileStore } from '@kevisual/use-config/file-store';
 | 
			
		||||
export const fileStore = useFileStore('proxy-upload');
 | 
			
		||||
 | 
			
		||||
@@ -37,7 +37,7 @@ type ConfigType = {
 | 
			
		||||
     * allow origin xiongxiao.me zxj.im silkyai.cn
 | 
			
		||||
     * 允许跨域访问的地址
 | 
			
		||||
     */
 | 
			
		||||
    allowOrigin: string[];
 | 
			
		||||
    allowedOrigin: string[];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * home 不在代理范围内跳转到的地址
 | 
			
		||||
@@ -46,4 +46,25 @@ type ConfigType = {
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const config = useConfig<ConfigType>();
 | 
			
		||||
// export const config = useConfig();
 | 
			
		||||
export const envConfig = useConfig() as any;
 | 
			
		||||
export const config: ConfigType = {
 | 
			
		||||
  api: {
 | 
			
		||||
    host: envConfig.API_HOST,
 | 
			
		||||
    path: envConfig.API_PATH,
 | 
			
		||||
    port: envConfig.PROXY_PORT,
 | 
			
		||||
  },
 | 
			
		||||
  apiList: [
 | 
			
		||||
    {
 | 
			
		||||
      path: '/api',
 | 
			
		||||
      target: envConfig.API_HOST,
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
  proxy: {
 | 
			
		||||
    port: envConfig.PROXY_PORT,
 | 
			
		||||
    domain: envConfig.PROXY_DOMAIN,
 | 
			
		||||
    resources: envConfig.PROXY_RESOURCES,
 | 
			
		||||
    allowedOrigin: (envConfig.PROXY_ALLOWED_ORIGINS as string)?.split(',') || [],
 | 
			
		||||
    home: envConfig.PROXY_HOME,
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,17 @@ export class UserApp {
 | 
			
		||||
      app: fetchData.key,
 | 
			
		||||
    };
 | 
			
		||||
    redis.set(key, data.user + ':' + data.app, 'EX', 60 * 60 * 24 * 7); // 7天
 | 
			
		||||
 | 
			
		||||
    const userDomainApp = 'user:domain:app:' + data.user + ':' + data.app;
 | 
			
		||||
 | 
			
		||||
    const domainKeys = await redis.get(userDomainApp);
 | 
			
		||||
    let domainKeysList = domainKeys ? JSON.parse(domainKeys) : [];
 | 
			
		||||
    domainKeysList.push(domain);
 | 
			
		||||
    const uniq = (arr: string[]) => {
 | 
			
		||||
      return [...new Set(arr)];
 | 
			
		||||
    };
 | 
			
		||||
    domainKeysList = uniq(domainKeysList);
 | 
			
		||||
    await redis.set(userDomainApp, JSON.stringify(domainKeysList), 'EX', 60 * 60 * 24 * 7); // 7天
 | 
			
		||||
    return data;
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
@@ -167,7 +178,7 @@ export class UserApp {
 | 
			
		||||
      console.log('fetchRes is error', fetchRes, 'user', user, 'app', app);
 | 
			
		||||
      return { code: 500, message: 'fetchRes is error' };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const loadStatus = await getAppLoadStatus(user, app);
 | 
			
		||||
    if (loadStatus.status === 'loading') {
 | 
			
		||||
      // 其他情况,error或者running都可以重新加载
 | 
			
		||||
@@ -282,6 +293,16 @@ export class UserApp {
 | 
			
		||||
    await redis.del('user:app:exist:' + app + ':' + user);
 | 
			
		||||
    await redis.del('user:app:set:' + app + ':' + user);
 | 
			
		||||
    await redis.del('user:app:status:' + app + ':' + user);
 | 
			
		||||
    const userDomainApp = 'user:domain:app:' + user + ':' + app;
 | 
			
		||||
    const domainKeys = await redis.get(userDomainApp);
 | 
			
		||||
    if (domainKeys) {
 | 
			
		||||
      const domainKeysList = JSON.parse(domainKeys);
 | 
			
		||||
      domainKeysList.forEach(async (domain: string) => {
 | 
			
		||||
        await redis.del('domain:' + domain);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    await redis.del(userDomainApp);
 | 
			
		||||
 | 
			
		||||
    // 删除所有文件
 | 
			
		||||
    deleteUserAppFiles(user, app);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
import { getDNS, isLocalhost } from '@/utils/dns.ts';
 | 
			
		||||
import http from 'http';
 | 
			
		||||
import https from 'https';
 | 
			
		||||
import { UserApp } from './get-user-app.ts';
 | 
			
		||||
import { config, fileStore } from '../module/config.ts';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
@@ -8,12 +7,11 @@ import fs from 'fs';
 | 
			
		||||
import { getContentType } from './get-content-type.ts';
 | 
			
		||||
import { createRefreshHtml } from './html/create-refresh-html.ts';
 | 
			
		||||
import { fileProxy } from './proxy/file-proxy.ts';
 | 
			
		||||
import net from 'net';
 | 
			
		||||
import { httpProxy } from './proxy/http-proxy.ts';
 | 
			
		||||
 | 
			
		||||
const api = config?.api || { host: 'kevisual.xiongxiao.me', path: '/api/router' };
 | 
			
		||||
const domain = config?.proxy?.domain || 'kevisual.xiongxiao.me';
 | 
			
		||||
const allowedOrigins = config?.proxy?.allowOrigin || [];
 | 
			
		||||
const allowedOrigins = config?.proxy?.allowedOrigin || [];
 | 
			
		||||
const home = config?.proxy?.home || '/ai/chat';
 | 
			
		||||
 | 
			
		||||
const noProxyUrl = ['/', '/favicon.ico'];
 | 
			
		||||
@@ -43,6 +41,9 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
 | 
			
		||||
    }
 | 
			
		||||
    // 提取req的headers中的非HOST的header
 | 
			
		||||
    const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host');
 | 
			
		||||
    const host = req.headers['host'];
 | 
			
		||||
    console.log('host', host);
 | 
			
		||||
    console.log('headers', headers);
 | 
			
		||||
    headers.forEach((item) => {
 | 
			
		||||
      header[item] = req.headers[item];
 | 
			
		||||
    });
 | 
			
		||||
@@ -96,6 +97,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
 | 
			
		||||
 | 
			
		||||
  let user, app;
 | 
			
		||||
  let domainApp = false;
 | 
			
		||||
  console.log('dns.hostName', dns.hostName, domain);
 | 
			
		||||
  if (isLocalhost(dns.hostName)) {
 | 
			
		||||
    // 本地开发环境 测试
 | 
			
		||||
    // user = 'root';
 | 
			
		||||
@@ -223,6 +225,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
 | 
			
		||||
    // console.log('isExist', isExist);
 | 
			
		||||
    if (!appFile) {
 | 
			
		||||
      const [indexFilePath, etag] = indexFile.split('||');
 | 
			
		||||
      // console.log('indexFilePath', indexFile, path.join(fileStore, indexFilePath));
 | 
			
		||||
      const contentType = getContentType(indexFilePath);
 | 
			
		||||
      const isHTML = contentType.includes('html');
 | 
			
		||||
      const filePath = path.join(fileStore, indexFilePath);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,21 @@
 | 
			
		||||
import { Client, ClientOptions } from 'minio';
 | 
			
		||||
import { useConfig } from '@kevisual/use-config';
 | 
			
		||||
 | 
			
		||||
type MinioConfig = {
 | 
			
		||||
  minio: ClientOptions & { bucketName: string };
 | 
			
		||||
import { Client } from 'minio';
 | 
			
		||||
import { useConfig } from '@kevisual/use-config/env';
 | 
			
		||||
const config = useConfig();
 | 
			
		||||
const minioConfig = {
 | 
			
		||||
  bucketName: config.MINIO_BUCKET_NAME,
 | 
			
		||||
  endPoint: config.MINIO_ENDPOINT,
 | 
			
		||||
  port: config.MINIO_PORT,
 | 
			
		||||
  useSSL: config.MINIO_USE_SSL === 'true',
 | 
			
		||||
  accessKey: config.MINIO_ACCESS_KEY,
 | 
			
		||||
  secretKey: config.MINIO_SECRET_KEY,
 | 
			
		||||
};
 | 
			
		||||
const config = useConfig<MinioConfig>();
 | 
			
		||||
const { bucketName, ...minioRest } = config.minio;
 | 
			
		||||
const { port, endPoint, useSSL } = minioRest;
 | 
			
		||||
// const config = useConfig<MinioConfig>();
 | 
			
		||||
const { port, endPoint, useSSL } = minioConfig;
 | 
			
		||||
export const minioUrl = `http${useSSL ? 's' : ''}://${endPoint}:${port || 9000}`;
 | 
			
		||||
export const minioResources = `${minioUrl}/resources`;
 | 
			
		||||
export const minioClient = new Client(minioRest);
 | 
			
		||||
export { bucketName };
 | 
			
		||||
export const minioClient = new Client(minioConfig);
 | 
			
		||||
export const bucketName = minioConfig.bucketName;
 | 
			
		||||
 | 
			
		||||
if (!minioClient) {
 | 
			
		||||
  throw new Error('Minio client not initialized');
 | 
			
		||||
}
 | 
			
		||||
// 验证权限
 | 
			
		||||
// (async () => {
 | 
			
		||||
//   const bucketExists = await minioClient.bucketExists(bucketName);
 | 
			
		||||
//   if (!bucketExists) {
 | 
			
		||||
//     await minioClient.makeBucket(bucketName);
 | 
			
		||||
//   }
 | 
			
		||||
//   const res = await minioClient.putObject(bucketName, 'private/test/a.b', 'test');
 | 
			
		||||
//   console.log('minio putObject', res);
 | 
			
		||||
 | 
			
		||||
// })();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import { Redis } from 'ioredis';
 | 
			
		||||
import { useConfig } from '@kevisual/use-config';
 | 
			
		||||
import { useContextKey } from '@kevisual/use-config/context';
 | 
			
		||||
console.log(process.env.REDIS_HOST);
 | 
			
		||||
 | 
			
		||||
const config = useConfig<{
 | 
			
		||||
  redis: ConstructorParameters<typeof Redis>;
 | 
			
		||||
}>();
 | 
			
		||||
const redisConfig = {
 | 
			
		||||
  host: 'localhost', // Redis 服务器的主机名或 IP 地址
 | 
			
		||||
  port: 6379, // Redis 服务器的端口号
 | 
			
		||||
  // password: 'your_password', // Redis 的密码 (如果有)
 | 
			
		||||
};
 | 
			
		||||
const init = () => {
 | 
			
		||||
  return new Redis({
 | 
			
		||||
    host: 'localhost', // Redis 服务器的主机名或 IP 地址
 | 
			
		||||
@@ -17,7 +19,7 @@ const init = () => {
 | 
			
		||||
      return Math.min(times * 50, 2000); // 每次重试时延迟增加
 | 
			
		||||
    },
 | 
			
		||||
    maxRetriesPerRequest: null, // 允许请求重试的次数 (如果需要无限次重试)
 | 
			
		||||
    ...config.redis,
 | 
			
		||||
    ...redisConfig,
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
// 配置 Redis 连接
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,15 @@
 | 
			
		||||
import { useConfig } from '@kevisual/use-config';
 | 
			
		||||
import { Sequelize } from 'sequelize';
 | 
			
		||||
import { useContextKey, useContext } from '@kevisual/use-config/context';
 | 
			
		||||
import { useConfig } from '@kevisual/use-config/env';
 | 
			
		||||
const config = useConfig();
 | 
			
		||||
 | 
			
		||||
type PostgresConfig = {
 | 
			
		||||
  postgres: {
 | 
			
		||||
    username: string;
 | 
			
		||||
    password: string;
 | 
			
		||||
    host: string;
 | 
			
		||||
    port: number;
 | 
			
		||||
    database: string;
 | 
			
		||||
  };
 | 
			
		||||
const postgresConfig = {
 | 
			
		||||
  username: config.POSTGRES_USERNAME,
 | 
			
		||||
  password: config.POSTGRES_PASSWORD,
 | 
			
		||||
  host: config.POSTGRES_HOST,
 | 
			
		||||
  port: config.POSTGRES_PORT,
 | 
			
		||||
  database: config.POSTGRES_DATABASE,
 | 
			
		||||
};
 | 
			
		||||
const config = useConfig<PostgresConfig>();
 | 
			
		||||
 | 
			
		||||
const postgresConfig = config.postgres;
 | 
			
		||||
 | 
			
		||||
if (!postgresConfig) {
 | 
			
		||||
  console.error('postgres config is required');
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user