test
This commit is contained in:
		
							
								
								
									
										11
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -23,6 +23,12 @@ importers:
 | 
			
		||||
      fast-glob:
 | 
			
		||||
        specifier: ^3.3.3
 | 
			
		||||
        version: 3.3.3
 | 
			
		||||
      pocketbase:
 | 
			
		||||
        specifier: ^0.26.2
 | 
			
		||||
        version: 0.26.2
 | 
			
		||||
      unstorage:
 | 
			
		||||
        specifier: ^1.17.1
 | 
			
		||||
        version: 1.17.1(idb-keyval@6.2.2)
 | 
			
		||||
    devDependencies:
 | 
			
		||||
      '@kevisual/local-proxy':
 | 
			
		||||
        specifier: ^0.0.6
 | 
			
		||||
@@ -2010,6 +2016,9 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
 | 
			
		||||
    engines: {node: '>=12'}
 | 
			
		||||
 | 
			
		||||
  pocketbase@0.26.2:
 | 
			
		||||
    resolution: {integrity: sha512-WA8EOBc3QnSJh8rJ3iYoi9DmmPOMFIgVfAmIGux7wwruUEIzXgvrO4u0W2htfQjGIcyezJkdZOy5Xmh7SxAftw==}
 | 
			
		||||
 | 
			
		||||
  postcss@8.5.6:
 | 
			
		||||
    resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
 | 
			
		||||
    engines: {node: ^10 || ^12 || >=14}
 | 
			
		||||
@@ -4837,6 +4846,8 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  picomatch@4.0.3: {}
 | 
			
		||||
 | 
			
		||||
  pocketbase@0.26.2: {}
 | 
			
		||||
 | 
			
		||||
  postcss@8.5.6:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      nanoid: 3.3.11
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,8 @@
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@kevisual/noco": "^0.0.1",
 | 
			
		||||
    "@kevisual/router": "^0.0.29",
 | 
			
		||||
    "fast-glob": "^3.3.3"
 | 
			
		||||
    "fast-glob": "^3.3.3",
 | 
			
		||||
    "pocketbase": "^0.26.2",
 | 
			
		||||
    "unstorage": "^1.17.1"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								server/src/cache/index.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								server/src/cache/index.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
import { createStorage } from 'unstorage'
 | 
			
		||||
import fsLiteDriver from "unstorage/drivers/fs-lite";
 | 
			
		||||
import { codeRoot } from '@/modules/config.ts';
 | 
			
		||||
import memoryDriver from "unstorage/drivers/memory";
 | 
			
		||||
 | 
			
		||||
export const storage = createStorage({
 | 
			
		||||
  // @ts-ignore
 | 
			
		||||
  driver: memoryDriver(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const codeStorage = createStorage({
 | 
			
		||||
  // @ts-ignore
 | 
			
		||||
  driver: fsLiteDriver({
 | 
			
		||||
    base: './code'
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// storage.setItem('test-ke/test-key.json', 'test-value');
 | 
			
		||||
// console.log('Cache test-key:', await storage.getItem('test-key'));
 | 
			
		||||
 | 
			
		||||
storage.setItem('root/light-code-demo/main.ts', 'test-value2');
 | 
			
		||||
console.log('Cache test-key:', await storage.getItem('root/light-code-demo/main.ts'));
 | 
			
		||||
console.log('has', await codeStorage.hasItem('root/light-code-demo/main.ts'));
 | 
			
		||||
							
								
								
									
										52
									
								
								server/src/db/collections/project.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								server/src/db/collections/project.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
 | 
			
		||||
import { Field } from '../types/index.ts';
 | 
			
		||||
 | 
			
		||||
export const projectStatus = ['提交', '审核中', '审核通过']; // 提交,审核中,审核通过
 | 
			
		||||
export type projectStatus = typeof projectStatus[number];
 | 
			
		||||
 | 
			
		||||
export const projectFields: Field[] = [
 | 
			
		||||
  {
 | 
			
		||||
    name: 'title',
 | 
			
		||||
    type: 'text',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'description',
 | 
			
		||||
    type: 'text',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'status',
 | 
			
		||||
    type: 'text'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'key',
 | 
			
		||||
    type: 'text',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'owner',
 | 
			
		||||
    type: 'text',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'data',
 | 
			
		||||
    type: 'json'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'files',
 | 
			
		||||
    type: 'json'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "createdAt",
 | 
			
		||||
    onCreate: true,
 | 
			
		||||
    onUpdate: false,
 | 
			
		||||
    type: "autodate"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "updatedAt",
 | 
			
		||||
    onCreate: true,
 | 
			
		||||
    onUpdate: true,
 | 
			
		||||
    type: "autodate"
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export const name = 'xx_projects';
 | 
			
		||||
 | 
			
		||||
export const type = 'base';
 | 
			
		||||
							
								
								
									
										37
									
								
								server/src/db/init.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								server/src/db/init.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
import { pb, db } from '../modules/db.ts'
 | 
			
		||||
import * as projects from './collections/project.ts'
 | 
			
		||||
// 要求
 | 
			
		||||
// 1. collection只做新增,不做修改
 | 
			
		||||
// 2. collection不存在就创建
 | 
			
		||||
// 3. 每一个collection的定义在文档中需要有
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const main = async () => {
 | 
			
		||||
  try {
 | 
			
		||||
    await db.ensureLogin().catch(() => { throw new Error('Login failed'); });
 | 
			
		||||
    // 程序第一次运行的时候执行,如果已经初始化过则跳过
 | 
			
		||||
    const collections = await db.pb.collections.getFullList({
 | 
			
		||||
      filter: 'name ~ "xx_%"',
 | 
			
		||||
    })
 | 
			
		||||
    console.log('Existing collections:', collections.map(c => c.name));
 | 
			
		||||
    const dbs = [projects]
 | 
			
		||||
    for (const coll of dbs) {
 | 
			
		||||
      const exists = collections.find(c => c.name === coll.name)
 | 
			
		||||
      if (exists) {
 | 
			
		||||
        console.log(`Collection ${coll.name} already exists, skipping creation.`);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      // 第一步,获取那个叉叉开头的 Collection。第二步,获取它的版本。
 | 
			
		||||
      const createdCollection = await db.pb.collections.create({
 | 
			
		||||
        name: coll.name,
 | 
			
		||||
        type: coll?.type || 'base',
 | 
			
		||||
        fields: coll?.projectFields,
 | 
			
		||||
      })
 | 
			
		||||
      console.log('Created collection:', createdCollection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.error('Error during DB initialization:', error);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										26
									
								
								server/src/db/types/collection.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								server/src/db/types/collection.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
export type Field = {
 | 
			
		||||
  /**
 | 
			
		||||
   * The unique identifier for the field
 | 
			
		||||
   */
 | 
			
		||||
  id?: string;
 | 
			
		||||
  /**
 | 
			
		||||
   * The name of the field
 | 
			
		||||
   */
 | 
			
		||||
  name: string;
 | 
			
		||||
  type?: 'text' | 'json' | 'autodate' | 'boolean' | 'number' | 'email' | 'url' | 'file' | 'relation';
 | 
			
		||||
  /**
 | 
			
		||||
   * Indicates whether the field is required
 | 
			
		||||
   */
 | 
			
		||||
  required?: boolean;
 | 
			
		||||
  /**
 | 
			
		||||
   * Only for 'autodate' type
 | 
			
		||||
   * Indicates whether to set the date on record creation or update
 | 
			
		||||
   */
 | 
			
		||||
  onCreate?: boolean;
 | 
			
		||||
  /** Only for 'autodate' type
 | 
			
		||||
   * Indicates whether to set the date on record update
 | 
			
		||||
   */
 | 
			
		||||
  onUpdate?: boolean;
 | 
			
		||||
  options?: Record<string, any>;
 | 
			
		||||
  [key: string]: any;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								server/src/db/types/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								server/src/db/types/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
export * from './collection.ts';
 | 
			
		||||
							
								
								
									
										7
									
								
								server/src/modules/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								server/src/modules/config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
import { useConfig } from '@kevisual/use-config'
 | 
			
		||||
 | 
			
		||||
import path from 'path';
 | 
			
		||||
 | 
			
		||||
export const config = useConfig()
 | 
			
		||||
 | 
			
		||||
export const codeRoot = path.join(process.cwd(), 'code');
 | 
			
		||||
							
								
								
									
										24
									
								
								server/src/modules/db.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								server/src/modules/db.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import PocketBase from 'pocketbase';
 | 
			
		||||
 | 
			
		||||
const POCKETBASE_URL = 'https://pocketbase.pro.xiongxiao.me/';
 | 
			
		||||
 | 
			
		||||
export const pb = new PocketBase(POCKETBASE_URL);
 | 
			
		||||
 | 
			
		||||
export class DB {
 | 
			
		||||
  pb: PocketBase
 | 
			
		||||
  constructor(pb: PocketBase) {
 | 
			
		||||
    this.pb = pb
 | 
			
		||||
  }
 | 
			
		||||
  async ensureLogin() {
 | 
			
		||||
    const pb = this.pb;
 | 
			
		||||
    if (!pb.authStore.isValid) {
 | 
			
		||||
      await pb.collection("_superusers").authWithPassword('xiongxiao@xiongxiao.me', '123456xx');
 | 
			
		||||
    }
 | 
			
		||||
    return pb.authStore.record;
 | 
			
		||||
  }
 | 
			
		||||
  async getCollection(name: string) {
 | 
			
		||||
    await this.ensureLogin();
 | 
			
		||||
    return this.pb.collection(name);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
export const db = new DB(pb);
 | 
			
		||||
							
								
								
									
										8
									
								
								server/src/routes/auth.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								server/src/routes/auth.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import { app } from '../app.ts'
 | 
			
		||||
 | 
			
		||||
app.route({
 | 
			
		||||
  path: 'auth',
 | 
			
		||||
  id: 'auth'
 | 
			
		||||
}).define(async (ctx) => {
 | 
			
		||||
  // Authentication logic here
 | 
			
		||||
}).addTo(app);
 | 
			
		||||
@@ -2,9 +2,10 @@ import { app } from '@/app.ts';
 | 
			
		||||
import path from 'node:path'
 | 
			
		||||
import glob from 'fast-glob';
 | 
			
		||||
import fs from 'node:fs'
 | 
			
		||||
import { codeRoot } from '@/modules/config.ts';
 | 
			
		||||
const list = async () => {
 | 
			
		||||
  const root = path.join(process.cwd(), 'code');
 | 
			
		||||
  const files = await glob('**/*.ts', { cwd: root });
 | 
			
		||||
 | 
			
		||||
  const files = await glob('**/*.ts', { cwd: codeRoot });
 | 
			
		||||
  type FileContent = {
 | 
			
		||||
    path: string;
 | 
			
		||||
    content: string;
 | 
			
		||||
@@ -12,7 +13,7 @@ const list = async () => {
 | 
			
		||||
  const filesContent: FileContent[] = [];
 | 
			
		||||
  for (const file of files) {
 | 
			
		||||
    if (file.startsWith('node_modules') || file.startsWith('dist') || file.startsWith('.git')) continue;
 | 
			
		||||
    const fullPath = path.join(root, file);
 | 
			
		||||
    const fullPath = path.join(codeRoot, file);
 | 
			
		||||
    const content = fs.readFileSync(fullPath, 'utf-8');
 | 
			
		||||
    if (content) {
 | 
			
		||||
      filesContent.push({ path: file, content: content });
 | 
			
		||||
@@ -20,9 +21,19 @@ const list = async () => {
 | 
			
		||||
  }
 | 
			
		||||
  return filesContent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app.route({
 | 
			
		||||
  path: 'file-code'
 | 
			
		||||
}).define(async (ctx) => {
 | 
			
		||||
  const files = await list();
 | 
			
		||||
  ctx.body = files
 | 
			
		||||
}).addTo(app);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
app.route({
 | 
			
		||||
  path: 'file-code',
 | 
			
		||||
  key: 'upload',
 | 
			
		||||
  middleware: ['auth']
 | 
			
		||||
}).define(async (ctx) => {
 | 
			
		||||
 | 
			
		||||
}).addTo(app)
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
import './call/index.ts';
 | 
			
		||||
 | 
			
		||||
import './file-code/index.ts';
 | 
			
		||||
 | 
			
		||||
import './auth.ts'
 | 
			
		||||
		Reference in New Issue
	
	Block a user