temp
This commit is contained in:
		
							
								
								
									
										13
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					node_modules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pack-dist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.env*
 | 
				
			||||||
 | 
					!.en*example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					kevisual-sync.db
 | 
				
			||||||
							
								
								
									
										13
									
								
								kevisual.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								kevisual.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "version": "0.0.1",
 | 
				
			||||||
 | 
					  "description": "Sync Projects",
 | 
				
			||||||
 | 
					  "ignore": [
 | 
				
			||||||
 | 
					    "node_modules",
 | 
				
			||||||
 | 
					    "dist"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  "sync": {
 | 
				
			||||||
 | 
					    "./tsconfig.json": {
 | 
				
			||||||
 | 
					      "url": "https://kevisual.cn/root/ai/tsconfig.json"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "@kevisual/sync",
 | 
				
			||||||
 | 
					  "version": "0.0.1",
 | 
				
			||||||
 | 
					  "description": "",
 | 
				
			||||||
 | 
					  "main": "index.js",
 | 
				
			||||||
 | 
					  "scripts": {
 | 
				
			||||||
 | 
					    "test": "bun src/test/index.ts "
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "keywords": [],
 | 
				
			||||||
 | 
					  "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
 | 
				
			||||||
 | 
					  "license": "MIT",
 | 
				
			||||||
 | 
					  "packageManager": "pnpm@10.6.2",
 | 
				
			||||||
 | 
					  "type": "module",
 | 
				
			||||||
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "@kevisual/db": "^0.0.1",
 | 
				
			||||||
 | 
					    "@kevisual/router": "^0.0.13",
 | 
				
			||||||
 | 
					    "@kevisual/types": "^0.0.9",
 | 
				
			||||||
 | 
					    "@types/better-sqlite3": "^7.6.13",
 | 
				
			||||||
 | 
					    "@types/bun": "^1.2.12",
 | 
				
			||||||
 | 
					    "@types/crypto-js": "^4.2.2",
 | 
				
			||||||
 | 
					    "@types/node": "^22.15.13",
 | 
				
			||||||
 | 
					    "commander": "^13.1.0",
 | 
				
			||||||
 | 
					    "crypto-js": "^4.2.0",
 | 
				
			||||||
 | 
					    "eventemitter3": "^5.0.1",
 | 
				
			||||||
 | 
					    "fast-glob": "^3.3.3",
 | 
				
			||||||
 | 
					    "sequelize": "^6.37.7",
 | 
				
			||||||
 | 
					    "sqlite3": "^5.1.7"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "pnpm": {
 | 
				
			||||||
 | 
					    "onlyBuiltDependencies": [
 | 
				
			||||||
 | 
					      "sqlite3"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1473
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1473
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								src/app.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/app.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					import { QueryRouterServer } from '@kevisual/router';
 | 
				
			||||||
 | 
					import { SyncConfig } from './modules/sync-config/config.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const app = new QueryRouterServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const syncConfig = new SyncConfig();
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/db/file-model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/db/file-model.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					import { DBModel, DataTypes, SyncOptions } from '@kevisual/db';
 | 
				
			||||||
 | 
					import { Stat } from './stat.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class FileModel extends DBModel {
 | 
				
			||||||
 | 
					  declare id: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare filepath: string; // 是唯一的
 | 
				
			||||||
 | 
					  declare filename: string;
 | 
				
			||||||
 | 
					  declare stat: Stat;
 | 
				
			||||||
 | 
					  declare hash: string;
 | 
				
			||||||
 | 
					  declare cwd: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async initModel(sequelize: any, syncOpts?: SyncOptions) {
 | 
				
			||||||
 | 
					    FileModel.init(
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        id: {
 | 
				
			||||||
 | 
					          type: DataTypes.UUID,
 | 
				
			||||||
 | 
					          defaultValue: DataTypes.UUIDV4,
 | 
				
			||||||
 | 
					          primaryKey: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        filepath: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        filename: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        stat: {
 | 
				
			||||||
 | 
					          type: DataTypes.JSON,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        hash: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        sequelize,
 | 
				
			||||||
 | 
					        modelName: 'file',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    if (syncOpts) {
 | 
				
			||||||
 | 
					      await FileModel.sync(syncOpts);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/db/manage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/db/manage.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import { DataSource } from '@kevisual/db';
 | 
				
			||||||
 | 
					import { FileModel } from './file-model.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const dataSource = new DataSource();
 | 
				
			||||||
							
								
								
									
										72
									
								
								src/db/model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/db/model.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					import { DBModel, DataTypes, SyncOptions } from '@kevisual/db';
 | 
				
			||||||
 | 
					import { Stat } from './stat.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class SyncModel extends DBModel {
 | 
				
			||||||
 | 
					  declare id: string;
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * URL 同步地址
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  declare url: string;
 | 
				
			||||||
 | 
					  declare syncData: Object;
 | 
				
			||||||
 | 
					  declare remoteData: Object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare markId: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare filepath: string; // 是唯一的
 | 
				
			||||||
 | 
					  declare filename: string;
 | 
				
			||||||
 | 
					  declare stat: Stat;
 | 
				
			||||||
 | 
					  declare hash: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async initModel(sequelize: any, syncOpts?: SyncOptions) {
 | 
				
			||||||
 | 
					    SyncModel.init(
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        id: {
 | 
				
			||||||
 | 
					          type: DataTypes.UUID,
 | 
				
			||||||
 | 
					          defaultValue: DataTypes.UUIDV4,
 | 
				
			||||||
 | 
					          primaryKey: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        url: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        syncData: {
 | 
				
			||||||
 | 
					          type: DataTypes.JSON,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					          defaultValue: {},
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        remoteData: {
 | 
				
			||||||
 | 
					          type: DataTypes.JSON,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					          defaultValue: {},
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        markId: {
 | 
				
			||||||
 | 
					          type: DataTypes.UUID,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        filepath: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        filename: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        stat: {
 | 
				
			||||||
 | 
					          type: DataTypes.JSON,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        hash: {
 | 
				
			||||||
 | 
					          type: DataTypes.STRING,
 | 
				
			||||||
 | 
					          allowNull: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        sequelize,
 | 
				
			||||||
 | 
					        modelName: 'sync',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    if (syncOpts) {
 | 
				
			||||||
 | 
					      await SyncModel.sync(syncOpts);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/db/stat.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/db/stat.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					import fs from 'node:fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Stat = {
 | 
				
			||||||
 | 
					  dev: number;
 | 
				
			||||||
 | 
					  ino: number;
 | 
				
			||||||
 | 
					  mode: number;
 | 
				
			||||||
 | 
					  nlink: number;
 | 
				
			||||||
 | 
					  uid: number;
 | 
				
			||||||
 | 
					  gid: number;
 | 
				
			||||||
 | 
					  rdev: number;
 | 
				
			||||||
 | 
					  size: number;
 | 
				
			||||||
 | 
					  blksize: number;
 | 
				
			||||||
 | 
					  blocks: number;
 | 
				
			||||||
 | 
					  atimeMs: number;
 | 
				
			||||||
 | 
					  mtimeMs: number;
 | 
				
			||||||
 | 
					  ctimeMs: number;
 | 
				
			||||||
 | 
					  birthtimeMs: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getStat = async (path: string): Promise<Stat> => {
 | 
				
			||||||
 | 
					  const _stat = await fs.promises.stat(path);
 | 
				
			||||||
 | 
					  return JSON.parse(JSON.stringify(_stat));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import { app, syncConfig } from './app.ts';
 | 
				
			||||||
 | 
					import './routes/index.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { app, syncConfig };
 | 
				
			||||||
							
								
								
									
										56
									
								
								src/modules/sync-config/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/modules/sync-config/config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					import { EventEmitter } from 'eventemitter3';
 | 
				
			||||||
 | 
					import { KevisualConfig, readKevisualConfig, writeKevisualConfig } from './kevisual.ts';
 | 
				
			||||||
 | 
					import { createSqlite } from '@kevisual/db';
 | 
				
			||||||
 | 
					const KEVISUAL_CONFIG_FILENAME = 'kevisual.json';
 | 
				
			||||||
 | 
					const DB_FILENAME = 'kevisual-sync.db';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					export const initConfigPath = (rootPath: string) => {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    workPath: path.resolve(rootPath),
 | 
				
			||||||
 | 
					    dbPath: path.join(rootPath, DB_FILENAME),
 | 
				
			||||||
 | 
					    configPath: path.join(rootPath, KEVISUAL_CONFIG_FILENAME),
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type SyncConfigOpts = {
 | 
				
			||||||
 | 
					  workPath?: string;
 | 
				
			||||||
 | 
					  init?: boolean;
 | 
				
			||||||
 | 
					  emitter?: EventEmitter;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export class SyncConfig {
 | 
				
			||||||
 | 
					  workPath: string;
 | 
				
			||||||
 | 
					  emitter: EventEmitter;
 | 
				
			||||||
 | 
					  isInit: boolean = false;
 | 
				
			||||||
 | 
					  configPath: ReturnType<typeof initConfigPath>;
 | 
				
			||||||
 | 
					  config: KevisualConfig;
 | 
				
			||||||
 | 
					  sequelize: ReturnType<typeof createSqlite>;
 | 
				
			||||||
 | 
					  constructor(opts?: SyncConfigOpts) {
 | 
				
			||||||
 | 
					    this.workPath = opts?.workPath || process.cwd();
 | 
				
			||||||
 | 
					    if (opts?.init) this.init();
 | 
				
			||||||
 | 
					    this.emitter = opts?.emitter ?? new EventEmitter();
 | 
				
			||||||
 | 
					    this.configPath = initConfigPath(this.workPath);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async init() {
 | 
				
			||||||
 | 
					    this.isInit = true;
 | 
				
			||||||
 | 
					    this.config = await readKevisualConfig(this.configPath.configPath);
 | 
				
			||||||
 | 
					    this.emitter.emit('init', true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async writeConfig(config: KevisualConfig) {
 | 
				
			||||||
 | 
					    this.config = { ...this.config, ...config };
 | 
				
			||||||
 | 
					    await writeKevisualConfig(this.configPath.configPath, this.config);
 | 
				
			||||||
 | 
					    return this.config;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async initDB() {
 | 
				
			||||||
 | 
					    if (this.sequelize) return this.sequelize;
 | 
				
			||||||
 | 
					    console.log('init db', this.configPath.dbPath);
 | 
				
			||||||
 | 
					    this.sequelize = createSqlite({ storage: this.configPath.dbPath, logging: false });
 | 
				
			||||||
 | 
					    return this.sequelize;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async onInit() {
 | 
				
			||||||
 | 
					    if (this.isInit) return true;
 | 
				
			||||||
 | 
					    return await new Promise((resolve) => {
 | 
				
			||||||
 | 
					      this.emitter.once('init', resolve);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								src/modules/sync-config/kevisual.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/modules/sync-config/kevisual.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					import fs from 'node:fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type KevisualConfig = {
 | 
				
			||||||
 | 
					  ignore?: string[];
 | 
				
			||||||
 | 
					  sync?: {
 | 
				
			||||||
 | 
					    [key: string]: {
 | 
				
			||||||
 | 
					      url: string;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const readKevisualConfig = async (path: string): Promise<KevisualConfig> => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const data = await fs.promises.readFile(path, 'utf-8');
 | 
				
			||||||
 | 
					    return JSON.parse(data);
 | 
				
			||||||
 | 
					  } catch (e) {
 | 
				
			||||||
 | 
					    return {};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const writeKevisualConfig = async (path: string, config: KevisualConfig): Promise<KevisualConfig> => {
 | 
				
			||||||
 | 
					  let _config = await readKevisualConfig(path);
 | 
				
			||||||
 | 
					  _config = { ..._config, ...config };
 | 
				
			||||||
 | 
					  await fs.promises.writeFile(path, JSON.stringify(_config, null, 2));
 | 
				
			||||||
 | 
					  return _config;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/routes/files/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/routes/files/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					import './list.ts'
 | 
				
			||||||
							
								
								
									
										65
									
								
								src/routes/files/list.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/routes/files/list.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					import { app, syncConfig } from '@/app.ts';
 | 
				
			||||||
 | 
					import FastGlob from 'fast-glob';
 | 
				
			||||||
 | 
					import { MD5 } from 'crypto-js';
 | 
				
			||||||
 | 
					import fs from 'node:fs';
 | 
				
			||||||
 | 
					import { getStat } from '@/db/stat.ts';
 | 
				
			||||||
 | 
					import { FileModel } from '@/db/file-model.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app
 | 
				
			||||||
 | 
					  .route({
 | 
				
			||||||
 | 
					    path: 'file',
 | 
				
			||||||
 | 
					    key: 'list',
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .define(async (ctx) => {
 | 
				
			||||||
 | 
					    const files = await FastGlob(['**/*'], {
 | 
				
			||||||
 | 
					      cwd: syncConfig.workPath,
 | 
				
			||||||
 | 
					      onlyFiles: true,
 | 
				
			||||||
 | 
					      absolute: false,
 | 
				
			||||||
 | 
					      ignore: ['node_modules'],
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    ctx.body = files;
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .addTo(app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app
 | 
				
			||||||
 | 
					  .route({
 | 
				
			||||||
 | 
					    path: 'file',
 | 
				
			||||||
 | 
					    key: 'init',
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .define(async (ctx) => {
 | 
				
			||||||
 | 
					    const files = await FastGlob(['**/*'], {
 | 
				
			||||||
 | 
					      cwd: syncConfig.workPath,
 | 
				
			||||||
 | 
					      onlyFiles: true,
 | 
				
			||||||
 | 
					      absolute: false,
 | 
				
			||||||
 | 
					      ignore: ['node_modules'],
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const result: any[] = [];
 | 
				
			||||||
 | 
					    for (let i = 0; i < files.length; i++) {
 | 
				
			||||||
 | 
					      const file = files[i];
 | 
				
			||||||
 | 
					      const content = fs.readFileSync(file, 'utf-8');
 | 
				
			||||||
 | 
					      const hash = MD5(content).toString();
 | 
				
			||||||
 | 
					      const stat = await getStat(file);
 | 
				
			||||||
 | 
					      const filename = file.split('/').pop();
 | 
				
			||||||
 | 
					      result.push({ filepath: file, filename: filename, hash, stat });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const sequelize = await syncConfig.initDB();
 | 
				
			||||||
 | 
					    await FileModel.initModel(sequelize, { alter: true });
 | 
				
			||||||
 | 
					    await FileModel.destroy({ where: {} })
 | 
				
			||||||
 | 
					    const create = await FileModel.bulkCreate(result);
 | 
				
			||||||
 | 
					    console.log(create);
 | 
				
			||||||
 | 
					    ctx.body = result;
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .addTo(app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app
 | 
				
			||||||
 | 
					  .route({
 | 
				
			||||||
 | 
					    path: 'file',
 | 
				
			||||||
 | 
					    key: 'get-sql',
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .define(async (ctx) => {
 | 
				
			||||||
 | 
					    const sequelize = await syncConfig.initDB();
 | 
				
			||||||
 | 
					    await FileModel.initModel(sequelize);
 | 
				
			||||||
 | 
					    const sql = await FileModel.findAll();
 | 
				
			||||||
 | 
					    ctx.body = sql.map((item) => item.toJSON());
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  .addTo(app);
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/routes/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/routes/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					import './files/index.ts'
 | 
				
			||||||
							
								
								
									
										3
									
								
								src/test/cmd.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/test/cmd.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					import { app, syncConfig } from '@/index.ts';
 | 
				
			||||||
 | 
					import { program, Command } from 'commander';
 | 
				
			||||||
 | 
					export { program, app, syncConfig, Command };
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/test/command/file-list.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/test/command/file-list.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					import { app, syncConfig, program, Command } from '../cmd.ts';
 | 
				
			||||||
 | 
					import fs from 'node:fs';
 | 
				
			||||||
 | 
					import util from 'node:util';
 | 
				
			||||||
 | 
					const main = async () => {
 | 
				
			||||||
 | 
					  const res = await app.queryRoute({ path: 'file', key: 'list' });
 | 
				
			||||||
 | 
					  console.log(res);
 | 
				
			||||||
 | 
					  const kv = syncConfig.configPath.configPath;
 | 
				
			||||||
 | 
					  const stat = fs.statSync(kv);
 | 
				
			||||||
 | 
					  console.log(JSON.parse(JSON.stringify(stat)));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cmd = new Command('file-list').description('list files').action(main);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					program.addCommand(cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const initMain = async () => {
 | 
				
			||||||
 | 
					  const res = await app.queryRoute({ path: 'file', key: 'init' });
 | 
				
			||||||
 | 
					  console.log(util.inspect(res, { depth: 10, colors: true }));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const cmd2 = new Command('file-init').description('list files').action(initMain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					program.addCommand(cmd2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getSql = async () => {
 | 
				
			||||||
 | 
					  const res = await app.queryRoute({ path: 'file', key: 'get-sql' });
 | 
				
			||||||
 | 
					  console.log(util.inspect(res, { depth: 10, colors: true }));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cmd3 = new Command('file-get-sql').description('list files').action(getSql);
 | 
				
			||||||
 | 
					program.addCommand(cmd3);
 | 
				
			||||||
							
								
								
									
										3
									
								
								src/test/command/resolve.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/test/command/resolve.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					import path from 'node:path'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log('resolve', path.resolve('./file-list.ts').replace(process.cwd()+'/', ''))
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/test/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/test/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import { program } from './cmd.ts';
 | 
				
			||||||
 | 
					import './command/file-list.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					program.parse(process.argv);
 | 
				
			||||||
							
								
								
									
										17
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "extends": "@kevisual/types/json/backend.json",
 | 
				
			||||||
 | 
					  "compilerOptions": {
 | 
				
			||||||
 | 
					    "baseUrl": ".",
 | 
				
			||||||
 | 
					    "typeRoots": [
 | 
				
			||||||
 | 
					      "node_modules/@types"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "paths": {
 | 
				
			||||||
 | 
					      "@/*": [
 | 
				
			||||||
 | 
					        "src/*"
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "include": [
 | 
				
			||||||
 | 
					    "src/**/*"
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user