文件结构更改

This commit is contained in:
undefined committed 2020-08-04 13:42:42 +08:00
1 parent b3af28dc43
commit 1f1d12ad73
109 files changed
+544 -3296

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
dist
*.d.ts
*.js
+32 -13
View File
@@ -1,20 +1,39 @@
name: Build
name: CI
on:
push:
branches:
- master
- push
- pull_request
env:
CI: true
jobs:
build:
name: Build
runs-on: ubuntu-latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- name: Check out
uses: actions/checkout@v1
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: '13.x'
- run: |
yarn
yarn build
- uses: JS-DevTools/npm-publish@v1
node-version: 13.x
- name: Create .npmrc
run: 'echo "//registry.npmjs.org/:_authToken=${{secrets.NPM_TOKEN}}" > .npmrc'
- name: Install
run: yarn
- name: Build
run: yarn build
- name: Lint
run: yarn lint
- name: Unit Test
run: yarn jest --runInBand
- name: Report Coverage
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.NPM_TOKEN }}
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage/lcov.info
name: codecov
- name: Publish
run: node build/publish.js
+9 -2
View File
@@ -2,8 +2,6 @@ node_modules/
config.yaml
config.json
.build/
*.build
public/
dist/
.cache/
*.cache
@@ -11,5 +9,14 @@ __*
ui/misc/.iconfont
ui/static/locale
*.log
*.d.ts
build/*.js
*.js.map
*.hydro
!.gitkeep
tsconfig.tsbuildinfo
yarn.lock
packages/**/*.js
packages/**/*.js.map
packages/**/*.d.ts
-14
View File
@@ -1,14 +0,0 @@
node_modules/
ui/
config.yaml
config.json
.cache/
*.cache
__*
*.log
*.hydro
locales
templates
.vscode
.github
examples
-21
View File
@@ -1,21 +0,0 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/.build/app.js",
"preLaunchTask": "npm: build",
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
}
]
}
-13
View File
@@ -1,13 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "build",
"group": "build",
"problemMatcher": [],
"label": "npm: build",
"detail": "node build --development"
}
]
}
-1
View File
@@ -3,7 +3,6 @@
Hydro是一个高效的信息学在线测评系统。特点:易于部署,轻量,功能强大且易于扩展。
[中文文档](https://hydro.js.org/)
[Hydro UI 传送门](https://github.com/hydro-dev/ui-default)
如果您认为本项目有价值,欢迎 star 。
相关文档若说明的不够详细,请提交 Pull Request 或联系开发组说明。
-56
View File
@@ -1,56 +0,0 @@
#!/usr/bin/env node
const os = require('os');
const path = require('path');
const cluster = require('cluster');
const fs = require('fs-extra');
const { argv } = require('yargs');
const hydro = require('../dist/loader');
if (!cluster.isMaster) {
// Forked by hydro
hydro.load().catch((e) => {
console.error(e);
process.exit(1);
});
} else {
fs.ensureDirSync(path.resolve(os.homedir(), '.hydro'));
const addonPath = path.resolve(os.homedir(), '.hydro', 'addon.json');
if (!fs.existsSync(addonPath)) fs.writeFileSync(addonPath, '[]');
let addons = JSON.parse(fs.readFileSync(addonPath).toString());
try {
const ui = argv.ui || '@hydrooj/ui-default';
require.resolve(ui);
addons.push(ui);
} catch (e) {
console.error('Please also install @hydrooj/ui-default');
}
if (argv._[0] && argv._[0] !== 'cli') {
const operation = argv._[0];
const arg1 = argv._[1];
const arg2 = argv._[2];
if (operation === 'addon') {
if (arg1 === 'add') addons.push(arg2);
else if (arg1 === 'remove') {
for (let i = 0; i < addons.length; i++) {
if (addons[i] === arg2) {
addons.splice(i, 1);
break;
}
}
}
addons = Array.from(new Set(addons));
console.log('Current Addons: ', addons);
fs.writeFileSync(addonPath, JSON.stringify(addons, null, 2));
}
} else {
addons = Array.from(new Set(addons));
for (const addon of addons) hydro.addon(addon);
(argv._[0] === 'cli' ? hydro.loadCli : hydro.load)().catch((e) => {
console.error(e);
process.exit(1);
});
}
}
+25
View File
@@ -0,0 +1,25 @@
/* eslint-disable import/no-extraneous-dependencies */
import spawn from 'cross-spawn';
const args = ['jest', '--coverage'];
const [, , argv2, argv3] = process.argv;
if (argv2 && !argv2.startsWith('-')) {
args.push(argv2);
if (argv3 && !argv3.startsWith('-')) {
args.push('--collectCoverageFrom');
if (argv3.endsWith('.ts')) {
args.push(`**/${argv3}`);
} else {
args.push(`**/${argv3}/**/*.ts`);
}
args.push(...process.argv.slice(4));
} else {
args.push(...process.argv.slice(3));
}
} else {
args.push('packages/.+\\.spec\\.ts', ...process.argv.slice(2));
}
spawn('npx', args, { stdio: 'inherit' });
+54
View File
@@ -0,0 +1,54 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable consistent-return */
/* eslint-disable no-await-in-loop */
/* eslint-disable import/no-dynamic-require */
import { gt } from 'semver';
import latest from 'latest-version';
import ora from 'ora';
import {
PackageJson, getWorkspaces, spawnAsync,
} from './utils';
const {
CI, GITHUB_EVENT_NAME, GITHUB_REF,
} = process.env;
if (CI && (GITHUB_REF !== 'refs/heads/master' || GITHUB_EVENT_NAME !== 'push')) {
console.log('publish skipped.');
process.exit(0);
}
(async () => {
let folders = await getWorkspaces();
if (process.argv[2]) {
folders = folders.filter((path) => path.startsWith(process.argv[2]));
}
const spinner = ora();
const bumpMap: Record<string, string> = {};
let progress = 0;
spinner.start(`Loading workspaces (0/${folders.length})`);
await Promise.all(folders.map(async (name) => {
let meta: PackageJson;
try {
meta = require(`../${name}/package`);
if (!meta.private) {
const version = await latest(meta.name);
if (gt(meta.version, version)) {
bumpMap[name] = meta.version;
}
}
} catch { /* pass */ }
spinner.text = `Loading workspaces (${++progress}/${folders.length})`;
}));
spinner.succeed();
if (Object.keys(bumpMap).length) {
for (const name in bumpMap) {
console.log(`publishing ${name}@${bumpMap[name]} ...`);
await spawnAsync(`yarn publish ${name} --new-version ${bumpMap[name]} --access public`);
}
}
console.log('Release created successfully.');
})();
+42
View File
@@ -0,0 +1,42 @@
import path from 'path';
import globby from 'globby';
import spawn from 'cross-spawn';
export const cwd = path.resolve(__dirname, '..');
export function getWorkspaces() {
return globby(require('../package').workspaces, {
cwd,
deep: 0,
onlyDirectories: true,
expandDirectories: false,
});
}
export type DependencyType = 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies'
export interface PackageJson extends Partial<Record<DependencyType, Record<string, string>>> {
name?: string
private?: boolean
version?: string
}
export function spawnSync(command: string, silent?: boolean) {
if (!silent) console.log(`$ ${command}`);
const args = command.split(/\s+/);
const result = spawn.sync(args[0], [...args.slice(1), '--color'], { cwd, encoding: 'utf8' });
if (result.status) {
throw new Error(result.stderr);
} else {
if (!silent) console.log(result.stdout);
return result.stdout.trim();
}
}
export function spawnAsync(command: string) {
const args = command.split(/\s+/);
const child = spawn(args[0], args.slice(1), { stdio: 'inherit' });
return new Promise((resolve, reject) => {
child.on('close', resolve);
});
}
+22
View File
@@ -0,0 +1,22 @@
module.exports = {
globals: {
'ts-jest': {
diagnostics: {
warnOnly: true,
},
},
},
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'js', 'json'],
moduleNameMapper: {
'[\\w-]+': '<rootDir>/packages/$0/src',
},
coverageProvider: 'v8',
coverageReporters: ['text', 'lcov'],
coveragePathIgnorePatterns: [
'node_modules/',
'tests/',
'dist/',
],
};
+33 -79
View File
@@ -1,81 +1,35 @@
{
"name": "hydrooj",
"version": "2.12.1",
"main": "dist/loader.js",
"bin": "bin/hydrooj.js",
"repository": "https://github.com/hydro-dev/Hydro.git",
"author": "masnn",
"license": "GPL-3.0-only",
"engines": {
"node": ">=10.10"
},
"dependencies": {
"adm-zip": "^0.4.16",
"ansi_up": "^4.0.4",
"cookies": "^0.8.0",
"detect-browser": "^5.1.1",
"fs-extra": "^9.0.1",
"html-to-text": "^5.1.1",
"js-yaml": "^3.13.1",
"koa": "^2.13.0",
"koa-body": "^4.2.0",
"koa-morgan": "^1.0.1",
"koa-router": "^8.0.8",
"koa-static-cache": "^5.1.3",
"lodash": "^4.17.19",
"lru-cache": "^6.0.0",
"markdown-it": "^11.0.0",
"markdown-it-anchor": "^5.3.0",
"markdown-it-footnote": "^3.0.2",
"markdown-it-imsize": "^2.0.1",
"markdown-it-mark": "^3.0.0",
"markdown-it-table-of-contents": "^0.4.4",
"moment-timezone": "^0.5.31",
"mongodb": "^3.5.9",
"nodemailer": "^6.4.10",
"nunjucks": "^3.2.2",
"prismjs": "^1.20.0",
"proxy-agent": "^3.1.1",
"ps-list": "^7.2.0",
"serialize-javascript": "^4.0.0",
"sockjs": "^0.3.20",
"superagent": "^5.2.2",
"systeminformation": "^4.26.10",
"yargs": "^15.4.1"
},
"devDependencies": {
"@types/adm-zip": "^0.4.33",
"@types/fs-extra": "^9.0.1",
"@types/html-to-text": "^5.1.1",
"@types/js-yaml": "^3.12.5",
"@types/katex": "^0.11.0",
"@types/koa": "^2.11.3",
"@types/koa-morgan": "^1.0.4",
"@types/koa-router": "^7.4.1",
"@types/koa-static-cache": "^5.1.0",
"@types/lodash": "^4.14.158",
"@types/lru-cache": "^5.1.0",
"@types/markdown-it": "^10.0.1",
"@types/mongodb": "^3.5.25",
"@types/node": "^14.0.24",
"@types/nodemailer": "^6.4.0",
"@types/nunjucks": "^3.1.3",
"@types/prismjs": "^1.16.1",
"@types/serialize-javascript": "^4.0.0",
"@types/sockjs": "^0.3.32",
"@types/superagent": "^4.1.8",
"@types/yargs": "^15.0.5",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"eslint": "^7.5.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-import-resolver-typescript": "^2.0.0",
"eslint-plugin-import": "^2.20.2",
"typescript": "^3.9.7"
},
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"lint": "eslint bin hydro tool --ext ts,js --fix"
}
"name": "hydro-workspace",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"build": "tsc -b",
"build:watch": "tsc -b --watch",
"lint": "eslint packages/**/*.ts --fix",
"pub": "node build/publish",
"jest": "node build/jest",
"start": "node_modules/.bin/hydrooj"
},
"version": "1.0.0",
"license": "AGPL-3.0-only",
"devDependencies": {
"@types/cross-spawn": "^6.0.2",
"@types/node": "^14.0.27",
"@typescript-eslint/eslint-plugin": "^3.8.0",
"@typescript-eslint/parser": "^3.8.0",
"cross-spawn": "^7.0.3",
"eslint": "^7.6.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-import-resolver-typescript": "^2.2.0",
"eslint-plugin-import": "^2.22.0",
"globby": "^11.0.1",
"jest": "^26.2.2",
"latest-version": "^5.1.0",
"ora": "^4.0.5",
"semver": "^7.3.2",
"ts-jest": "^26.1.4",
"typescript": "^3.9.7"
}
}
+1
View File
@@ -0,0 +1 @@
这是Hydro的核心文件。
-1
View File
@@ -4,5 +4,4 @@ discussion前端权限节点显示异常?
SETTINGS_PRIVACY.allowRegisteredUsers
model.setting.ui.name
pdoc.secretConfig?
move to @hydrooj/core?
message.markAsRead
File renamed without changes.
File renamed without changes.
File renamed without changes.
+73
View File
@@ -0,0 +1,73 @@
{
"name": "hydrooj",
"version": "2.12.1",
"main": "dist/loader.js",
"bin": "bin/hydrooj.js",
"repository": "https://github.com/hydro-dev/Hydro.git",
"author": "masnn",
"license": "GPL-3.0-only",
"engines": {
"node": ">=10.10"
},
"dependencies": {
"adm-zip": "^0.4.16",
"ansi_up": "^4.0.4",
"cookies": "^0.8.0",
"detect-browser": "^5.1.1",
"fs-extra": "^9.0.1",
"html-to-text": "^5.1.1",
"js-yaml": "^3.13.1",
"koa": "^2.13.0",
"koa-body": "^4.2.0",
"koa-morgan": "^1.0.1",
"koa-router": "^8.0.8",
"koa-static-cache": "^5.1.3",
"lodash": "^4.17.19",
"lru-cache": "^6.0.0",
"markdown-it": "^11.0.0",
"markdown-it-anchor": "^5.3.0",
"markdown-it-footnote": "^3.0.2",
"markdown-it-imsize": "^2.0.1",
"markdown-it-mark": "^3.0.0",
"markdown-it-table-of-contents": "^0.4.4",
"moment-timezone": "^0.5.31",
"mongodb": "^3.5.9",
"mongodb-watcher": "^1.3.0",
"nodemailer": "^6.4.10",
"nunjucks": "^3.2.2",
"prismjs": "^1.20.0",
"proxy-agent": "^3.1.1",
"ps-list": "^7.2.0",
"serialize-javascript": "^4.0.0",
"sockjs": "^0.3.20",
"superagent": "^5.2.2",
"systeminformation": "^4.26.10",
"yargs": "^15.4.1"
},
"devDependencies": {
"@types/adm-zip": "^0.4.33",
"@types/fs-extra": "^9.0.1",
"@types/html-to-text": "^5.1.1",
"@types/js-yaml": "^3.12.5",
"@types/katex": "^0.11.0",
"@types/koa": "^2.11.3",
"@types/koa-morgan": "^1.0.4",
"@types/koa-router": "^7.4.1",
"@types/koa-static-cache": "^5.1.0",
"@types/lodash": "^4.14.158",
"@types/lru-cache": "^5.1.0",
"@types/markdown-it": "^10.0.1",
"@types/mongodb": "^3.5.25",
"@types/nodemailer": "^6.4.0",
"@types/nunjucks": "^3.1.3",
"@types/prismjs": "^1.16.1",
"@types/serialize-javascript": "^4.0.0",
"@types/sockjs": "^0.3.32",
"@types/superagent": "^4.1.8",
"@types/yargs": "^15.0.5"
},
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,5 @@
import mongodb from 'mongodb';
import MongoWatcher from 'mongodb-watcher';
import * as bus from './bus';
import options from '../options';
@@ -15,6 +16,12 @@ mongodb.MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopolog
.then((Client) => {
db = Client.db(opts.name);
global.Hydro.service.db.db = db;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const watcher = new MongoWatcher(db, {
longCursorThreshold: 100,
largeInsertThreshold: 1024 * 30,
largeFetchThreshold: 1024 * 30,
});
bus.publish('system_database_connected', null);
});
File renamed without changes.
File renamed without changes.
@@ -278,6 +278,7 @@ export class Handler {
gravatar: misc.gravatar(this.user.gravatar || '', 128),
perm: this.user.perm.toString(),
};
if (!global.Hydro.lib.template) return JSON.stringify(context);
const res = await global.Hydro.lib.template.render(name, {
handler: this,
UserContext,
@@ -80,7 +80,7 @@ namespace Proxy {
}
declare module 'superagent' {
interface Request {
interface SuperAgentRequest {
proxy(url: string): this;
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
},
"include": [
"src",
]
}
+1
View File
@@ -0,0 +1 @@
# Login-With-Github
+59
View File
@@ -0,0 +1,59 @@
import 'hydrooj';
import superagent from 'superagent';
async function get() {
const { system, token } = global.Hydro.model;
const [appid, [state]] = await Promise.all([
system.get('login-with-github.id'),
token.add(token.TYPE_OAUTH, 600, { redirect: this.request.referer }),
]);
this.response.redirect = `https://github.com/login/oauth/authorize?client_id=${appid}&state=${state}`;
}
async function callback({ state, code }) {
const { system, token } = global.Hydro.model;
const { UserFacingError } = global.Hydro.error;
const [[appid, secret, proxy, url], s] = await Promise.all([
system.getMany([
'login-with-github.id',
'login-with-github.secret',
'login-with-github.proxy',
'server.url',
]),
token.get(state, token.TYPE_OAUTH),
]);
const res = await superagent.post('https://github.com/login/oauth/access_token')
.proxy(proxy)
.send({
client_id: appid,
client_secret: secret,
code,
redirect_uri: `${url}oauth/github/callback`,
state,
})
.set('accept', 'application/json');
if (res.body.error) {
throw new UserFacingError(
res.body.error, res.body.error_description, res.body.error_uri,
);
}
const t = res.body.access_token;
const userInfo = await superagent.get('https://api.github.com/user')
.proxy(proxy)
.set('User-Agent', 'Hydro-OAuth')
.set('Authorization', `token ${t}`);
const ret = {
email: userInfo.body.email,
bio: userInfo.body.bio,
uname: [userInfo.body.name, userInfo.body.login],
};
this.response.redirect = s.redirect;
await token.del(s._id, token.TYPE_OAUTH);
return ret;
}
global.Hydro.lib.oauth_github = {
text: 'Login with Github',
callback,
get,
};
+22
View File
@@ -0,0 +1,22 @@
{
"name": "@hydrooj/login-with-github",
"version": "0.0.2",
"main": "package.json",
"repository": "git@github.com:hydro-dev/Hydro.git",
"author": "undefined <masnn0@outlook.com>",
"license": "MIT",
"scripts": {
"lint": "eslint lib.ts --fix",
"build": "tsc"
},
"devDependencies": {
"@types/superagent": "^4.1.8",
"hydrooj": "2.12.1"
},
"peerDependencies": {
"hydrooj": "^2.12.1"
},
"dependencies": {
"superagent": "^5.3.1"
}
}
+15
View File
@@ -0,0 +1,15 @@
id:
type: text
category: system
desc: Github OAuth AppID
name: id
secret:
type: text
category: system
desc: Github OAuth Secret
name: secret
proxy:
type: text
category: system
desc: Github OAuth Proxy
name: proxy
+11
View File
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base",
"compilerOptions": {
"outDir": ".",
"rootDir": ".",
},
"include": [
"*.ts"
],
"exclude": []
}
+1
View File
@@ -0,0 +1 @@
# Login-With-Google
Loaded 100 of 109 files, more files were not shown because too many files have changed in this diff. Show more