wip: replace packages with pure files

This commit is contained in:
Justin Lin committed 2025-04-24 23:20:40 +08:00
1 parent 2d95ca382f
commit 87b8ca5d04
112 files changed
+740 -522

No files matched your search

+27 -6
View File
@@ -20,9 +20,12 @@ module.exports = {
settings: { settings: {
'import/resolver': { 'import/resolver': {
node: { node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'], extensions: ['.js', '.ts'],
moduleDirectory: ['node_modules', 'packages', 'server/src'],
},
typescript: {
alwaysTryTypes: true,
}, },
typescript: {},
}, },
vue: { vue: {
version: '3.0', // Explicitly specify Vue 3 version: '3.0', // Explicitly specify Vue 3
@@ -63,10 +66,10 @@ module.exports = {
// Allow missing file extensions // Allow missing file extensions
'import/extensions': [ 'import/extensions': [
'warn', 'off',
'ignorePackages', 'ignorePackages',
{ {
js: 'off', js: 'never',
jsx: 'never', jsx: 'never',
ts: 'never', ts: 'never',
tsx: 'never', tsx: 'never',
@@ -79,12 +82,30 @@ module.exports = {
'@typescript-eslint/no-empty-function': 'error', '@typescript-eslint/no-empty-function': 'error',
'no-shadow': 'off', 'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error', '@typescript-eslint/no-shadow': 'error',
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['../*'],
message: 'Relative imports are not allowed.',
allowSameFolder: true,
},
],
},
],
}, },
overrides: [ overrides: [
{ {
files: ['**/tests/**/*.js', '**/tests/**/*.ts', '**/*.test.ts'], // Adjust the pattern to match your test files files: ['**/tests/**/*.js', '**/tests/**/*.ts', '**/*.test.ts'],
rules: {
'import/extensions': 'off',
'import/no-extraneous-dependencies': 'off',
},
},
{
files: ['server/**/*.ts'],
rules: { rules: {
'import/extensions': 'off', // Turn off the rule for test files
'import/no-extraneous-dependencies': 'off', 'import/no-extraneous-dependencies': 'off',
}, },
}, },
+5 -9
View File
@@ -16,11 +16,6 @@
"@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^3.0.3", "@fortawesome/vue-fontawesome": "^3.0.3",
"@linux-odyssey/constants": "*",
"@linux-odyssey/file-graph": "*",
"@linux-odyssey/game": "*",
"@linux-odyssey/models": "*",
"@linux-odyssey/utils": "*",
"@trpc/client": "^11.1.0", "@trpc/client": "^11.1.0",
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"axios": "^1.6.0", "axios": "^1.6.0",
@@ -39,13 +34,14 @@
}, },
"devDependencies": { "devDependencies": {
"@types/validator": "^13.11.9", "@types/validator": "^13.11.9",
"@vitejs/plugin-vue": "^4.5.2",
"@vue/compiler-sfc": "^3.3.13", "@vue/compiler-sfc": "^3.3.13",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"postcss": "^8.4.31", "postcss": "^8.4.31",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.3",
"typescript": "^5.3.3", "@vitejs/plugin-vue": "^5.2.2",
"vite": "^4.5.3", "@vue/tsconfig": "^0.7.0",
"vue-tsc": "^2.0.10" "typescript": "~5.7.2",
"vite": "^6.3.1",
"vue-tsc": "^2.2.8"
} }
} }
+1 -1
View File
@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch, computed } from 'vue' import { ref, onMounted, watch, computed } from 'vue'
import { useToast } from 'vue-toastification' import { useToast } from 'vue-toastification'
import { DAG } from '@linux-odyssey/utils' import { DAG } from '../../../packages/utils'
import { trpc } from '../utils/trpc' import { trpc } from '../utils/trpc'
import useUserProfile from '../store/userProfile' import useUserProfile from '../store/userProfile'
import QuestIntro from './QuestIntro.vue' import QuestIntro from './QuestIntro.vue'
+7 -4
View File
@@ -1,10 +1,13 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { FileGraph, FileGraphUpdateEvent } from '@linux-odyssey/file-graph' import {
import { IResponse, ITask } from '@linux-odyssey/game' FileGraph,
import type { SessionDetail } from 'server/src/routers/sessionRouter' type FileGraphUpdateEvent,
} from '../../../packages/file-graph'
import type { IResponse, ITask } from '../../../packages/game'
import type { SessionDetail } from '../../../server/src/routers/sessionRouter'
import Socket from '../utils/socket' import Socket from '../utils/socket'
import SocketTerminal from '../utils/terminal' import SocketTerminal from '../utils/terminal'
import { Session } from '../types' import type { Session } from '../types'
import { trpc } from '../utils/trpc' import { trpc } from '../utils/trpc'
const socket = new Socket() const socket = new Socket()
+2 -2
View File
@@ -1,5 +1,5 @@
import { FileGraph } from '@linux-odyssey/file-graph' import { FileGraph } from '../../packages/file-graph'
import { IResponse, ITask } from '@linux-odyssey/game' import type { IResponse, ITask } from '../../packages/game'
export interface Task { export interface Task {
id: number id: number
+1 -1
View File
@@ -1,5 +1,5 @@
import { createTRPCClient, httpBatchLink } from '@trpc/client' import { createTRPCClient, httpBatchLink } from '@trpc/client'
import type { AppRouter } from 'server/src/routers' import type { AppRouter } from '../../../server/src/routers'
export const trpc = createTRPCClient<AppRouter>({ export const trpc = createTRPCClient<AppRouter>({
links: [ links: [
+1 -1
View File
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { isValidUsername } from '@linux-odyssey/utils' import { isValidUsername } from '../../../packages/utils'
import AuthForm from '../components/AuthForm.vue' import AuthForm from '../components/AuthForm.vue'
import Background from '../components/DynamicBackground.vue' import Background from '../components/DynamicBackground.vue'
import { TooManyRequestsError, ValidationError } from '../utils/errors' import { TooManyRequestsError, ValidationError } from '../utils/errors'
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import validator from 'validator' import validator from 'validator'
import { isValidUsername } from '@linux-odyssey/utils' import { isValidUsername } from '../../../packages/utils'
import { passwordPolicy } from '@linux-odyssey/constants' import { passwordPolicy } from '../../../packages/constants'
import AuthForm from '../components/AuthForm.vue' import AuthForm from '../components/AuthForm.vue'
import DynamicBackground from '../components/DynamicBackground.vue' import DynamicBackground from '../components/DynamicBackground.vue'
import HeaderPart from '../components/header/HeaderPart.vue' import HeaderPart from '../components/header/HeaderPart.vue'
+14
View File
@@ -0,0 +1,14 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
+3 -23
View File
@@ -1,27 +1,7 @@
{ {
"compilerOptions": { "files": [],
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true
},
"include": ["src/**/*.ts", "src/**/*.vue"],
"references": [ "references": [
{ "path": "../packages/utils" }, { "path": "./tsconfig.app.json" },
{ "path": "../packages/constants" }, { "path": "./tsconfig.node.json" }
{ "path": "../packages/file-graph" },
{ "path": "../packages/models" }
] ]
} }
+24
View File
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
+10
View File
@@ -1,9 +1,19 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [vue()], plugins: [vue()],
resolve: {
alias: {
'@game': path.resolve(__dirname, '../packages/game'),
'@models': path.resolve(__dirname, '../packages/models'),
'@utils': path.resolve(__dirname, '../packages/utils'),
'@constants': path.resolve(__dirname, '../packages/constants'),
'@file-graph': path.resolve(__dirname, '../packages/file-graph'),
},
},
server: { server: {
proxy: { proxy: {
'/trpc': { '/trpc': {
-1
View File
@@ -12,7 +12,6 @@
"dev": "nodemon" "dev": "nodemon"
}, },
"dependencies": { "dependencies": {
"@linux-odyssey/models": "*",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.19.2", "express": "^4.19.2",
"express-basic-auth": "^1.2.1", "express-basic-auth": "^1.2.1",
+1 -1
View File
@@ -1,4 +1,4 @@
import connectDB from '@linux-odyssey/models' import connectDB from '@models'
import express from 'express' import express from 'express'
import { engine } from 'express-handlebars' import { engine } from 'express-handlebars'
import basicAuth from 'express-basic-auth' import basicAuth from 'express-basic-auth'
+1 -1
View File
@@ -1,4 +1,4 @@
import { Command } from '@linux-odyssey/models' import { Command } from '@models'
import Pagination from './pagination.js' import Pagination from './pagination.js'
// eslint-disable-next-line import/prefer-default-export // eslint-disable-next-line import/prefer-default-export
+1 -1
View File
@@ -1,6 +1,6 @@
/* eslint-disable object-shorthand */ /* eslint-disable object-shorthand */
/* eslint-disable func-names */ /* eslint-disable func-names */
import { UserProfile } from '@linux-odyssey/models' import { UserProfile } from '@models'
export function questList() { export function questList() {
return UserProfile.aggregate([ return UserProfile.aggregate([
+1 -1
View File
@@ -1,4 +1,4 @@
import { Command, Session } from '@linux-odyssey/models' import { Command, Session } from '@models'
import Pagination from './pagination.js' import Pagination from './pagination.js'
import { import {
CommandObject, CommandObject,
+1 -1
View File
@@ -1,4 +1,4 @@
import { Session, User } from '@linux-odyssey/models' import { Session, User } from '@models'
import { Types } from 'mongoose' import { Types } from 'mongoose'
import Pagination from './pagination.js' import Pagination from './pagination.js'
import { IUser, UserSessionDetail } from '../interface.js' import { IUser, UserSessionDetail } from '../interface.js'
File renamed without changes.
-17
View File
@@ -1,17 +0,0 @@
{
"name": "@linux-odyssey/constants",
"type": "module",
"version": "1.0.0",
"private": true,
"main": "dist/index.js",
"exports": "./dist/index.js",
"types": "dist/index.d.ts",
"license": "GPL",
"scripts": {
"build": "tsc",
"dev": "tsc -w"
},
"dependencies": {
"zod": "^3.23.8"
}
}
File renamed without changes.
-12
View File
@@ -1,12 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"module": "Node16",
"moduleResolution": "node16",
"outDir": "./dist",
"rootDir": "src"
},
"include": ["*.js", "*.ts", "src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
View File
@@ -0,0 +1,3 @@
export { default as File, FileObject } from './file'
export { default as FileNode, IFileNode } from './fileNode'
export { default as FileGraph, FileGraphUpdateEvent } from './fileGraph'
-20
View File
@@ -1,20 +0,0 @@
{
"name": "@linux-odyssey/file-graph",
"version": "1.0.0",
"type": "module",
"main": "./dist/cjs/index.js",
"types": "./dist/types/index.d.ts",
"exports": {
".": {
"require": "./dist/cjs/index.js",
"import": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts"
}
},
"license": "MIT",
"scripts": {
"build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json",
"dev": "tsc -w",
"test": "yarn build && jest"
}
}
-3
View File
@@ -1,3 +0,0 @@
export { default as File, FileObject } from './file.js'
export { default as FileNode, IFileNode } from './fileNode.js'
export { default as FileGraph, FileGraphUpdateEvent } from './fileGraph.js'
-9
View File
@@ -1,9 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "Node",
"outDir": "./dist/cjs",
"declarationDir": "./dist/types"
}
}
-15
View File
@@ -1,15 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"composite": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist/esm",
"declarationDir": "./dist/types",
"target": "ES2020",
"useDefineForClassFields": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
import { FileGraph, FileNode, IFileNode } from '@linux-odyssey/file-graph' import { FileGraph, IFileNode } from '../../packages/file-graph'
import { Quest } from './Quest' import { Quest } from './Quest'
import { import {
IQuest, IQuest,
@@ -7,7 +7,6 @@ import {
IFileExistenceChecker, IFileExistenceChecker,
IResponse, IResponse,
ITask, ITask,
ICommandParams,
} from './schema' } from './schema'
export class GameSession { export class GameSession {
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-21
View File
@@ -1,21 +0,0 @@
{
"name": "@linux-odyssey/game",
"version": "1.0.0",
"main": "dist/index.js",
"exports": {
".": "./dist/index.js"
},
"license": "MIT",
"scripts": {
"build": "tsc -b",
"generate": "tsx src/cli.ts"
},
"dependencies": {
"@linux-odyssey/file-graph": "*",
"zod": "^3.23.8"
},
"devDependencies": {
"tsx": "^4.19.3",
"zod-to-json-schema": "^3.24.5"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
import { IFileNode } from '@linux-odyssey/file-graph' import { IFileNode } from '../../file-graph'
export * from './condition.js' export * from './condition.js'
export * from './stage.js' export * from './stage.js'
File renamed without changes.
File renamed without changes.
File renamed without changes.
-11
View File
@@ -1,11 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"composite": true,
"module": "CommonJS",
"moduleResolution": "Node"
},
"include": ["src"]
}
File renamed without changes.
File renamed without changes.
-17
View File
@@ -1,17 +0,0 @@
{
"name": "@linux-odyssey/models",
"type": "module",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "GPL",
"exports": "./dist/index.js",
"scripts": {
"build": "tsc",
"dev": "tsc -w"
},
"dependencies": {
"@types/mongoose": "^5.11.97",
"mongoose": "^8.0.3"
}
}
File renamed without changes.
-10
View File
@@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"composite": true,
"outDir": "./dist"
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-13
View File
@@ -1,13 +0,0 @@
{
"name": "@linux-odyssey/utils",
"version": "1.0.0",
"main": "dist/index.js",
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
"license": "MIT",
"scripts": {
"build": "tsc",
"dev": "tsc -w"
}
}
-11
View File
@@ -1,11 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "./dist",
"composite": true,
"allowJs": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
+1 -1
View File
@@ -1,4 +1,4 @@
import connectDB, { User } from '@linux-odyssey/models' import connectDB, { User } from '@models'
async function migrate() { async function migrate() {
await connectDB( await connectDB(
-5
View File
@@ -1,5 +0,0 @@
{
"watch": ["src", "swagger.yaml", "../quests", "../packages"],
"ext": "js,ts,yaml,yml",
"exec": "node --loader ts-node/esm src/index.js"
}
+7 -15
View File
@@ -2,22 +2,15 @@
"name": "server", "name": "server",
"version": "0.0.0", "version": "0.0.0",
"description": "Linux Odyssey Server", "description": "Linux Odyssey Server",
"type": "module",
"scripts": { "scripts": {
"start": "node dist/index.js", "start": "tsx src/index.ts",
"setup": "node dist/cli/setup.js", "setup": "tsx src/cli/setup.js",
"clean": "node dist/cli/clean.js", "clean": "tsx src/cli/clean.js",
"build": "tsc -b", "type-check": "tsc --noEmit",
"dev": "nodemon", "dev": "tsx --watch src/index.ts",
"build:quests": "node dist/cli/build.js", "build:quests": "tsx src/cli/build.js"
"ts-node": "node --loader ts-node/esm"
}, },
"dependencies": { "dependencies": {
"@linux-odyssey/constants": "*",
"@linux-odyssey/game": "*",
"@linux-odyssey/file-graph": "*",
"@linux-odyssey/models": "*",
"@linux-odyssey/utils": "*",
"@trpc/server": "^11.1.0", "@trpc/server": "^11.1.0",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"commander": "^11.0.0", "commander": "^11.0.0",
@@ -44,6 +37,7 @@
"socket.io": "^4.7.1", "socket.io": "^4.7.1",
"ssh2": "^1.16.0", "ssh2": "^1.16.0",
"swagger-ui-express": "^5.0.0", "swagger-ui-express": "^5.0.0",
"tsx": "^4.19.3",
"validator": "^13.11.0", "validator": "^13.11.0",
"winston": "^3.11.0", "winston": "^3.11.0",
"yaml": "^2.3.1", "yaml": "^2.3.1",
@@ -70,10 +64,8 @@
"@types/validator": "^13.11.9", "@types/validator": "^13.11.9",
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
"jest": "^29.6.1", "jest": "^29.6.1",
"nodemon": "^3.0.1",
"regenerator-runtime": "^0.14.1", "regenerator-runtime": "^0.14.1",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"ts-node": "^10.9.2",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }
@@ -1,11 +1,11 @@
import { GameSession, commandSchema } from '@linux-odyssey/game' import { GameSession, commandSchema } from '../../../../packages/game'
import { Command, Session } from '@linux-odyssey/models' import { Command, Session } from '../../../../packages/models'
import type { Request, Response } from 'express' import type { Request, Response } from 'express'
import { pushToSession } from '../socket.js' import { pushToSession } from '../socket'
import { finishSession } from '../../models/sessionManager.js' import { finishSession } from '../../models/sessionManager'
import { asyncHandler } from '../../middleware/error.js' import { asyncHandler } from '../../middleware/error'
import { questManager } from '../../models/quest.js' import { questManager } from '../../models/quest'
import { CLIFileExistenceChecker } from '../../containers/cli.js' import { CLIFileExistenceChecker } from '../../containers/cli'
export const newCommand = asyncHandler(async (req: Request, res: Response) => { export const newCommand = asyncHandler(async (req: Request, res: Response) => {
const command = commandSchema.parse(req.body) const command = commandSchema.parse(req.body)
@@ -4,7 +4,7 @@ import { leaderboard } from '../../models/userManager.js'
export default asyncHandler(async (req: Request, res: Response) => { export default asyncHandler(async (req: Request, res: Response) => {
const users = await leaderboard() const users = await leaderboard()
const response = users.map((user) => ({ const response = users.map((user: any) => ({
username: user.user.username, username: user.user.username,
completedQuests: user.completedQuests, completedQuests: user.completedQuests,
score: user.score * 1000, score: user.score * 1000,
+1 -1
View File
@@ -3,7 +3,7 @@ import type { Socket } from 'socket.io'
import { Duplex } from 'stream' import { Duplex } from 'stream'
import validator from 'validator' import validator from 'validator'
import type { Server as HttpServer } from 'http' import type { Server as HttpServer } from 'http'
import { ISession, Session } from '@linux-odyssey/models' import { ISession, Session } from '../../../packages/models'
import { getAndStartContainer, attachContainer } from '../containers/docker.js' import { getAndStartContainer, attachContainer } from '../containers/docker.js'
import SessionMiddleware from '../middleware/session.js' import SessionMiddleware from '../middleware/session.js'
import { genJWT } from '../utils/auth.js' import { genJWT } from '../utils/auth.js'
+3 -3
View File
@@ -1,8 +1,8 @@
import { check } from 'express-validator' import { check } from 'express-validator'
import { isValidUsername, isValidEmail } from '@linux-odyssey/utils' import { isValidUsername, isValidEmail } from '../../../../packages/utils'
import { User } from '@linux-odyssey/models' import { User } from '../../../../packages/models'
import { passwordPolicy } from '@linux-odyssey/constants' import { passwordPolicy } from '../../../../packages/constants'
import { noError } from '../../middleware/validator.js' import { noError } from '../../middleware/validator.js'
const checkUsername = () => const checkUsername = () =>
+1 -1
View File
@@ -1,4 +1,4 @@
import { User } from '@linux-odyssey/models' import { User } from '../../../packages/models'
import type { Profile } from 'passport' import type { Profile } from 'passport'
import type { VerifyCallback } from 'passport-oauth2' import type { VerifyCallback } from 'passport-oauth2'
import logger from '../utils/logger.js' import logger from '../utils/logger.js'
+1 -1
View File
@@ -1,6 +1,6 @@
import passport from 'passport' import passport from 'passport'
import type { Express } from 'express' import type { Express } from 'express'
import { UserProfile } from '@linux-odyssey/models' import { UserProfile } from '../../../packages/models'
import passwordStrategy from './passwordStrategy.js' import passwordStrategy from './passwordStrategy.js'
import jwtStrategy from './jwtStrategy.js' import jwtStrategy from './jwtStrategy.js'
import googleStrategy from './googleStrategy.js' import googleStrategy from './googleStrategy.js'
+1 -1
View File
@@ -3,7 +3,7 @@ import bcrypt from 'bcrypt'
import { Strategy as LocalStrategy } from 'passport-local' import { Strategy as LocalStrategy } from 'passport-local'
import type { IVerifyOptions } from 'passport-local' import type { IVerifyOptions } from 'passport-local'
import type { Express } from 'express' import type { Express } from 'express'
import { User } from '@linux-odyssey/models' import { User } from '../../../packages/models'
async function verifyPassword( async function verifyPassword(
username: string, username: string,
+4 -4
View File
@@ -1,7 +1,7 @@
import connectDB from '@linux-odyssey/models' import connectDB from '../../../packages/models'
import { removeExpired } from '../containers/expiryChecker.js' import { removeExpired } from '../containers/expiryChecker'
import config from '../config.js' import config from '../config'
import logger from '../utils/logger.js' import logger from '../utils/logger'
connectDB(config.db) connectDB(config.db)
.then(removeExpired) .then(removeExpired)
+4 -6
View File
@@ -1,14 +1,13 @@
import validator from 'validator' import validator from 'validator'
import dotenv from 'dotenv' import { config as dotenvConfig } from 'dotenv'
import { fileURLToPath } from 'node:url'
import path from 'path' import path from 'path'
import { get } from './utils/env.js' import { get } from './utils/env.js'
import { loadOrCreateKeyPair } from './utils/crypto.js' import { loadOrCreateKeyPair } from './utils/crypto.js'
// Import dotenv and load ../.env // Import dotenv and load ../.env
dotenv.config({ path: '../.env' }) dotenvConfig({ path: '../.env' })
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
dotenv.config({ path: '../.env.dev' }) dotenvConfig({ path: '../.env.dev' })
} }
function getTrustProxies(key: string): string[] { function getTrustProxies(key: string): string[] {
@@ -93,8 +92,7 @@ function createConfig() {
} }
function getProjectRoot(): string { function getProjectRoot(): string {
const filename = fileURLToPath(import.meta.url) const root = path.join(path.dirname(__filename), '..', '..')
const root = path.join(path.dirname(filename), '..', '..')
return root return root
} }
+2 -2
View File
@@ -1,7 +1,7 @@
import { execFile } from 'child_process' import { execFile } from 'child_process'
import { buildFileCheckCmd } from '@linux-odyssey/utils' import { buildFileCheckCmd } from '../../../packages/utils'
import type { IFileExistenceChecker, IFileInput } from '@linux-odyssey/game' import type { IFileExistenceChecker, IFileInput } from '../../../packages/game'
function sanitizeId(id: string) { function sanitizeId(id: string) {
return id.replace(/[^a-zA-Z0-9]/g, '') return id.replace(/[^a-zA-Z0-9]/g, '')
+2 -2
View File
@@ -1,6 +1,6 @@
import schedule from 'node-schedule' import schedule from 'node-schedule'
import { Session } from '@linux-odyssey/models' import { Session } from '../../../packages/models'
import type { ISession } from '@linux-odyssey/models' import type { ISession } from '../../../packages/models'
import type { HydratedDocument } from 'mongoose' import type { HydratedDocument } from 'mongoose'
import config from '../config.js' import config from '../config.js'
import { deleteContainer } from './docker.js' import { deleteContainer } from './docker.js'
+1 -1
View File
@@ -5,7 +5,7 @@ import YAML from 'yaml'
import swaggerUI from 'swagger-ui-express' import swaggerUI from 'swagger-ui-express'
import passport from 'passport' import passport from 'passport'
import * as trpcExpress from '@trpc/server/adapters/express' import * as trpcExpress from '@trpc/server/adapters/express'
import connectDB from '@linux-odyssey/models' import connectDB from '../../packages/models'
import './auth/passport.js' import './auth/passport.js'
import socketServer from './api/socket.js' import socketServer from './api/socket.js'
+5 -1
View File
@@ -3,7 +3,11 @@ import fs from 'fs/promises'
import path from 'path' import path from 'path'
import yaml from 'yaml' import yaml from 'yaml'
import { questSchema, globalExceptionSchema, IQuest } from '@linux-odyssey/game' import {
questSchema,
globalExceptionSchema,
IQuest,
} from '../../../packages/game'
import logger from '../utils/logger.js' import logger from '../utils/logger.js'
class QuestValidationError extends Error { class QuestValidationError extends Error {
+3 -3
View File
@@ -1,6 +1,6 @@
import { HydratedDocument } from 'mongoose' import { HydratedDocument } from 'mongoose'
import { Session, UserProfile } from '@linux-odyssey/models' import { Session, UserProfile } from '../../../packages/models'
import type { ISession, IUser } from '@linux-odyssey/models' import type { ISession, IUser } from '../../../packages/models'
import { createContainer, deleteContainer } from '../containers/docker.js' import { createContainer, deleteContainer } from '../containers/docker.js'
import logger from '../utils/logger.js' import logger from '../utils/logger.js'
import { questManager } from './quest.js' import { questManager } from './quest.js'
@@ -113,7 +113,7 @@ export async function isQuestUnlocked(
if (!quest.requirements) { if (!quest.requirements) {
return true return true
} }
return quest.requirements.every((requiredQuestId) => { return quest.requirements.every((requiredQuestId: string) => {
const progress = userProfile.progress.get(requiredQuestId) const progress = userProfile.progress.get(requiredQuestId)
return progress && progress.completed return progress && progress.completed
}) })
+1 -1
View File
@@ -1,6 +1,6 @@
import { Express } from 'express' import { Express } from 'express'
import { format } from 'date-fns' import { format } from 'date-fns'
import { User, UserProfile } from '@linux-odyssey/models' import { User, UserProfile } from '../../../packages/models'
import { hashPassword } from '../utils/auth.js' import { hashPassword } from '../utils/auth.js'
export async function createUser( export async function createUser(
+2 -2
View File
@@ -1,6 +1,6 @@
import { TRPCError } from '@trpc/server' import { TRPCError } from '@trpc/server'
import { ISession, Session } from '@linux-odyssey/models' import { ISession, Session } from '../../../packages/models'
import { GameSession, VoidFileExistenceChecker } from '@linux-odyssey/game' import { GameSession, VoidFileExistenceChecker } from '../../../packages/game'
import { z } from 'zod' import { z } from 'zod'
import { createNewSession, isQuestUnlocked } from '../models/sessionManager.js' import { createNewSession, isQuestUnlocked } from '../models/sessionManager.js'
import config from '../config.js' import config from '../config.js'
+1 -1
View File
@@ -1,4 +1,4 @@
import { UserProfile } from '@linux-odyssey/models' import { UserProfile } from '../../../packages/models'
import { TRPCError } from '@trpc/server' import { TRPCError } from '@trpc/server'
import { protectedProcedure, router } from '../trpc.js' import { protectedProcedure, router } from '../trpc.js'
+1 -1
View File
@@ -1,4 +1,4 @@
import { User } from '@linux-odyssey/models' import { User } from '../../../packages/models'
import config from '../config.js' import config from '../config.js'
import { createUser } from '../models/userManager.js' import { createUser } from '../models/userManager.js'
import logger from './logger.js' import logger from './logger.js'
+3 -6
View File
@@ -1,16 +1,13 @@
{ {
"extends": "../tsconfig.json", "extends": "../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"module": "NodeNext",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"outDir": "./dist" "outDir": "./dist"
}, },
"include": ["src"], "include": ["src"],
"exclude": ["node_modules", "src/*.test.js", "dist"], "exclude": ["node_modules", "src/*.test.js", "dist"],
"references": [
{ "path": "../packages/constants" },
{ "path": "../packages/file-graph" },
{ "path": "../packages/models" },
{ "path": "../packages/utils" }
],
"ts-node": { "ts-node": {
"swc": true "swc": true
} }
+1 -15
View File
@@ -1,23 +1,9 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ESNext", // 要編譯成的 JS 目標版本
"module": "ESNext", // 要編譯成的 module
"moduleResolution": "NodeNext", // module 解析方式, default "classic"
"esModuleInterop": true, // module 兼容, 會影響 build 方式
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": true, "strict": true,
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"declaration": true, "baseUrl": "."
"declarationMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["*"],
"@app/*": ["app/*"],
"@server/*": ["server/*"],
"@models/*": ["packages/models/src/*"],
"@game/*": ["packages/game/src/*"],
"@file-graph/*": ["packages/file-graph/src/*"]
}
} }
} }
+24
View File
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+3
View File
@@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}
+5
View File
@@ -0,0 +1,5 @@
# Vue 3 + TypeScript + Vite
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.5.13"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.2",
"@vue/tsconfig": "^0.7.0",
"typescript": "~5.7.2",
"vite": "^6.3.1",
"vue-tsc": "^2.2.8"
}
}
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff. Show more