Commit 3f0e93d4 authored by nano's avatar nano

fix lint

parent 24bbadbe
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = 0
trim_trailing_whitespace = false
# Indentation override
#[lib/**.js]
#[{package.json,.travis.yml}]
#[**/**.js]
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<DBN-PSQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
<TypeScriptCodeStyleSettings>
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
</TypeScriptCodeStyleSettings>
<codeStyleSettings language="JavaScript">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="RIGHT_MARGIN" value="100" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="TsLint" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions" suppressed-tasks="Babel" />
</project>
\ No newline at end of file
This diff is collapsed.
import * as _fs from 'fs'
import * as path from 'path'
import * as fs from 'fs-extra-promise'
import {mongodb} from '../src/models/iridium'
import {crawlPath, caculateSHA256, archive, archiveSingle, untar} from "./utils";
import {Archive, File} from "../src/models/Package";
import {file} from "tmp";
import * as path from 'path';
import * as fs from 'fs-extra-promise';
import {archive, archiveSingle, caculateSHA256, crawlPath, untar} from './utils';
import {Archive, File} from '../src/models/Package';
const upload_path = path.join(__dirname, '../test/upload')
const release_path = path.join(__dirname, '../test/release')
const app_path = path.join(__dirname, '../test/apps')
const upload_path = path.join(__dirname, '../test/upload');
const release_path = path.join(__dirname, '../test/release');
const app_path = path.join(__dirname, '../test/apps');
export async function bundle(...args) {
const [package_id] = args
const [package_id] = args;
console.log(`package ${package_id}`);
await fs.ensureDirAsync(release_path)
await fs.ensureDirAsync(app_path)
await fs.ensureDirAsync(upload_path)
await fs.ensureDirAsync(release_path);
await fs.ensureDirAsync(app_path);
await fs.ensureDirAsync(upload_path);
const archive_path = path.join(release_path, 'downloads', package_id)
const archive_path = path.join(release_path, 'downloads', package_id);
const package_path = path.join(app_path, package_id);
const uploadFile_path = path.join(upload_path, package_id)
const full_path = path.join(archive_path, 'full')
const sand_path = path.join(archive_path, 'sand')
await fs.ensureDirAsync(archive_path)
await fs.ensureDirAsync(package_path)
await fs.ensureDirAsync(full_path)
await fs.ensureDirAsync(sand_path)
const uploadFile_path = path.join(upload_path, package_id);
const full_path = path.join(archive_path, 'full');
const sand_path = path.join(archive_path, 'sand');
await fs.ensureDirAsync(archive_path);
await fs.ensureDirAsync(package_path);
await fs.ensureDirAsync(full_path);
await fs.ensureDirAsync(sand_path);
// untar upload package
await untar(uploadFile_path, package_path)
await untar(uploadFile_path, package_path);
let files = new Map<string, File>();
let archives = new Map<string, Archive>();
......@@ -39,52 +36,51 @@ export async function bundle(...args) {
await crawlPath(package_path, {
relative: true,
onFile: async (file) => {
let file_hash = await caculateSHA256(file)
let file_hash = await caculateSHA256(file);
files.set(file, {
path: path.relative(package_path,file),
path: path.relative(package_path, file),
hash: file_hash,
size: (await fs.statAsync(file)).size
})
});
let sand_file = path.join(sand_path, `${file_hash}.tar.gz`)
let sand_file = path.join(sand_path, `${file_hash}.tar.gz`);
await archiveSingle(sand_file, [file], package_path)
await archiveSingle(sand_file, [file], package_path);
let sand_hash = await caculateSHA256(sand_file)
let sand_hash = await caculateSHA256(sand_file);
archives.set(sand_file, {
path: path.relative(sand_path, sand_file),
hash: sand_hash,
size: (await fs.statAsync(sand_file)).size
})
});
await fs.renameAsync(sand_file, path.join(path.dirname(sand_file), `${sand_hash}.tar.gz`))
await fs.renameAsync(sand_file, path.join(path.dirname(sand_file), `${sand_hash}.tar.gz`));
},
onDir: async (_files, _path, depth) => {
files.set(_path, {
path: path.relative(package_path, _path),
})
});
},
})
});
let filePath = path.join(full_path, `${package_id}.tar.gz`)
let filePath = path.join(full_path, `${package_id}.tar.gz`);
await fs.removeAsync(filePath)
await archive(filePath, await fs.readdirAsync(package_path), package_path)
await fs.removeAsync(filePath);
await archive(filePath, await fs.readdirAsync(package_path), package_path);
const fullHash = await caculateSHA256(filePath)
const fullSize = (await fs.statAsync(filePath)).size
const fullHash = await caculateSHA256(filePath);
const fullSize = (await fs.statAsync(filePath)).size;
let fullPath = path.join(path.dirname(filePath), `${fullHash}.tar.gz`)
await fs.renameAsync(filePath, fullPath)
let fullPath = path.join(path.dirname(filePath), `${fullHash}.tar.gz`);
await fs.renameAsync(filePath, fullPath);
return {
files: Array.from(files.values()),
archives: Array.from(archives.values()),
fullSize,
fullHash
}
};
}
import * as fs from 'fs-extra-promise'
import * as _fs from 'fs'
import * as crypto from 'crypto'
import * as child_process from 'child_process'
// import * as tar from 'tar-stream'
// import * as fstream from 'fstream'
import * as fs from 'fs-extra-promise';
import * as _fs from 'fs';
import * as crypto from 'crypto';
import * as child_process from 'child_process';
interface crawOptions {
onDir: (files: string | string[], _path: string, depth: number) => Promise<void>;
......@@ -12,32 +11,32 @@ interface crawOptions {
export async function crawlPath(_path, options: crawOptions, depth = 0) {
if (await isDir(_path)) {
depth += 1
const files = await fs.readdirAsync(_path)
await options.onDir(files, _path, depth)
depth += 1;
const files = await fs.readdirAsync(_path);
await options.onDir(files, _path, depth);
if (files) {
for (let fileName of files) {
const file = `${_path}/${fileName}`
const file = `${_path}/${fileName}`;
if (await isDir(file)) {
await crawlPath(file, options, depth)
await crawlPath(file, options, depth);
} else if (await isFile(file)) {
await options.onFile(file)
await options.onFile(file);
}
}
}
} else if (await isFile(_path)) {
await options.onFile(_path)
await options.onFile(_path);
}
}
export async function isDir(path) {
return (await fs.lstatAsync(path)).isDirectory()
return (await fs.lstatAsync(path)).isDirectory();
}
export async function isFile(path) {
return (await fs.lstatAsync(path)).isFile()
return (await fs.lstatAsync(path)).isFile();
}
......@@ -54,14 +53,14 @@ export function archiveSingle(archive: string, files: string[], directory: strin
let child = child_process.spawn("tar", ["-czf", archive, '-P', '-C', directory].concat(files), {stdio: 'inherit'});
child.on('exit', (code) => {
if (code == 0) {
resolve()
resolve();
} else {
reject(code);
}
});
child.on('error', (error) => {
reject(error);
})
});
});
}
......@@ -70,14 +69,14 @@ export function archive(archive: string, files: string[], directory: string): Pr
let child = child_process.spawn("tar", ["-vczf", archive, '-C', directory].concat(files), {stdio: 'inherit'});
child.on('exit', (code) => {
if (code == 0) {
resolve()
resolve();
} else {
reject(code);
}
});
child.on('error', (error) => {
reject(error);
})
});
});
}
......@@ -86,14 +85,14 @@ export function untar(archive: string, directory: string): Promise<void> {
let child = child_process.spawn("tar", ["-xvf", archive, '-C', directory], {stdio: 'inherit'});
child.on('exit', (code) => {
if (code == 0) {
resolve()
resolve();
} else {
reject(code);
}
});
child.on('error', (error) => {
reject(error);
})
});
});
}
......@@ -102,7 +101,7 @@ export function caculateSHA256(file: string): Promise<string> {
let input = _fs.createReadStream(file);
const hash = crypto.createHash("sha256");
hash.on("error", (error: Error) => {
reject(error)
reject(error);
});
input.on("error", (error: Error) => {
reject(error);
......
if(process.env.NODE_ENV !== 'production') {
require('dotenv').config()
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
import * as Koa from 'koa'
import * as log4js from 'log4js'
import * as bodyParser from 'koa-bodyparser'
import * as hbs from 'koa-hbs'
import { mongodb } from './src/models/iridium'
import * as Koa from 'koa';
import * as log4js from 'log4js';
import * as bodyParser from 'koa-bodyparser';
import * as hbs from 'koa-hbs';
import {mongodb} from './src/models/iridium';
// import index from './routes/index';
import upload from './src/routes/upload';
// import users from './src/routes/users';
import package from './src/routes/package'
import pack from './src/routes/package';
import apps from './src/routes/app';
// import packages from './routes/packages';
......@@ -20,48 +19,48 @@ const logger = log4js.getLogger();
const app = new Koa();
app.use(hbs.middleware({
viewPath: __dirname + '/views',
viewPath: __dirname + '/views',
}));
app.use(async(ctx, next) => {
const start = new Date();
await next();
const ms = Date.now() - start.getTime();
ctx.set('X-Response-Time', `${ms}ms`);
app.use(async (ctx, next) => {
const start = new Date();
await next();
const ms = Date.now() - start.getTime();
ctx.set('X-Response-Time', `${ms}ms`);
});
// 错误处理
app.use(async(ctx, next) => {
try {
await next();
} catch (err) {
// will only respond with JSON
console.log(err);
ctx.status = err.status || 500;
ctx.body = {
message: err.message,
};
if (err.errCode) {
ctx.body['errCode'] = err.errCode;
}
if (ctx.response.status >= 500) {
logger.error(err);
} else if (ctx.response.status >= 400) {
logger.warn(err);
}
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
// will only respond with JSON
console.log(err);
ctx.status = err.status || 500;
ctx.body = {
message: err.message,
};
if (err.errCode) {
ctx.body['errCode'] = err.errCode;
}
if (ctx.response.status >= 500) {
logger.error(err);
} else if (ctx.response.status >= 400) {
logger.warn(err);
}
}
});
// 跨域
app.use(async(ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH');
ctx.set('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With',);
if (ctx.method === 'OPTIONS') {
ctx.status = 204;
} else {
await next();
}
app.use(async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH');
ctx.set('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With',);
if (ctx.method === 'OPTIONS') {
ctx.status = 204;
} else {
await next();
}
});
......@@ -70,13 +69,13 @@ app.use(bodyParser());
// app.use(users.routes());
app.use(apps.routes());
app.use(upload.routes());
app.use(package.routes());
app.use(pack.routes());
// app.use(packages.routes());
mongodb.connect().then(() => {
app.listen(8001, () => {
console.log("app listening port 8001")
console.log('app listening port 8001');
});
})
});
/**
* Created by zh99998 on 2017/4/21.
*/
export function renderChecksum(files: { path: string, hash?: string }[]) {
return files.map(({ path, hash }) => `${hash || ''} ${path}`).join('\n');
}
// 用法示例
// const example = [
// { path: 'README', hash: '11111111111111111111111111111111', size: 1 },
// { path: 'main.exe', hash: '22222222222222222222222222222222', size: 2 },
// { path: 'assets' }, // 对于目录,置 hash 为空 (undefiend 或 不存在)
// { path: 'assets/1.png', hash: '33333333333333333333333333333333', size: 3 }
// ];
//
// console.log(renderChecksum(example));
import { Container } from 'inversify'
import TYPES from './types'
import {Container} from 'inversify';
const container = new Container()
const container = new Container();
export default container
\ No newline at end of file
export default container;
import {Core, Model, Instance, Collection, Index, Property, ObjectID} from 'iridium'
import {handleImg} from '../utils'
import {Collection, Index, Instance, Property} from 'iridium';
import {handleImg} from '../utils';
interface I18n<T> {
[locale: string]: T;
......@@ -9,7 +9,7 @@ interface Platform<T> {
[platform: string]: T;
}
interface Package{
interface Package {
id: string;
name: string;
platforms: Platform<string[]>;
......@@ -27,21 +27,21 @@ interface File {
export interface App {
id: string;
name?: I18n<string>;
description?: I18n<string>
developers?: I18n<[{ name: string, url: string }]>
publishers?: I18n<[{ name: string, url: string }]>
description?: I18n<string>;
developers?: I18n<[{ name: string, url: string }]>;
publishers?: I18n<[{ name: string, url: string }]>;
released_at?: string;
category?: string;
parent?: string;
tag?: string[];
tag?: string[];
dependencies?: Platform<string[]>;
references?: Platform<string[]>;
homepage?: string;
locales?: string[];
actions?: Platform<{[key: string]: {execuate: string, args: string[], env: {[key: string]: string}}}>;
files?: {[key: string]: { sync: boolean}}
actions?: Platform<{ [key: string]: { execuate: string, args: string[], env: { [key: string]: string } } }>;
files?: { [key: string]: { sync: boolean } };
version?: Platform<string>;
news?: I18n<{title: string, url: string, image: string}[]>;
news?: I18n<{ title: string, url: string, image: string }[]>;
conference?: string;
data?: any;
icon?: string;
......@@ -52,18 +52,18 @@ export interface App {
}
@Collection('apps')
@Index({id: 1}, { unique: true })
@Index({id: 1}, {unique: true})
export class AppSchema extends Instance<App, AppSchema> implements App {
@Property(String, true)
id: string;
@Property(Object, false)
name?: I18n<string>;
@Property(Object, false)
description?: I18n<string>
description?: I18n<string>;
@Property(Object, false)
developers?: I18n<[{ name: string, url: string }]>
developers?: I18n<[{ name: string, url: string }]>;
@Property(Object, false)
publishers?: I18n<[{ name: string, url: string }]>
publishers?: I18n<[{ name: string, url: string }]>;
@Property(String, false)
released_at?: string;
@Property(String, false)
......@@ -71,7 +71,7 @@ export class AppSchema extends Instance<App, AppSchema> implements App {
@Property(String, false)
parent?: string;
@Property(Array, false)
tag?: string[];
tag?: string[];
@Property(Object, false)
dependencies?: Platform<string[]>;
@Property(Object, false)
......@@ -81,13 +81,13 @@ export class AppSchema extends Instance<App, AppSchema> implements App {
@Property(Array, false)
locales?: string[];
@Property(Object, false)
actions?: Platform<{[key: string]: {execuate: string, args: string[], env: {[key: string]: string}}}>;
actions?: Platform<{ [key: string]: { execuate: string, args: string[], env: { [key: string]: string } } }>;
@Property(Object, false)
files?: {[key: string]: { sync: boolean}}
files?: { [key: string]: { sync: boolean } };
@Property(Object, false)
version?: Platform<string>;
@Property(Object, false)
news?: I18n<{title: string, url: string, image: string}[]>;
news?: I18n<{ title: string, url: string, image: string }[]>;
@Property(String, false)
conference?: string;
@Property(Object, false)
......@@ -103,23 +103,23 @@ export class AppSchema extends Instance<App, AppSchema> implements App {
@Property(Date, false)
created_at: Date;
static onCreating(app: App){
app.created_at = new Date()
static onCreating(app: App) {
app.created_at = new Date();
}
handleUpdate(data: App) {
Object.assign(this, data)
Object.assign(this, data);
}
toJSON() {
this.Convert()
return JSON.parse(this)
this.Convert();
return {...<Object>this};
}
Convert() {
this.icon = handleImg(this.icon),
this.icon = handleImg(this.icon),
this.cover = handleImg(this.cover),
this.background = handleImg(this.background)
this.background = handleImg(this.background);
}
}
import {Core, Model} from "iridium";
import {App, AppSchema} from "./App";
import {Package, PackageSchema} from "./Package";
import {Core, Model} from 'iridium';
import {App, AppSchema} from './App';
import {Package, PackageSchema} from './Package';
export class MongoDB extends Core {
Apps = new Model<App, AppSchema>(this, AppSchema)
Packages = new Model<Package, PackageSchema>(this,PackageSchema)
Apps = new Model<App, AppSchema>(this, AppSchema);
Packages = new Model<Package, PackageSchema>(this, PackageSchema);
}
export const mongodb = new MongoDB(process.env["MONGODB"])
export const mongodb = new MongoDB(process.env['MONGODB']);
import {Core, Model, Instance, Collection, Index, Property, ObjectID} from 'iridium'
import {Collection, Index, Instance, Property} from 'iridium';
type Locale = 'zh-CN' | 'en-US' | 'ja-JP'
type Platform = 'win32' | 'linux' | 'darwin'
type Locale = 'zh-CN' | 'en-US' | 'ja-JP';
type Platform = 'win32' | 'linux' | 'darwin';
export interface Action {
execute: string;
......@@ -26,8 +26,8 @@ export interface Package {
id: string;
name: string;
appId: string;
fullSize: number;
fullHash: string;
fullSize?: number;
fullHash?: string;
version: string;
status: string;
type: string;
......@@ -38,8 +38,8 @@ export interface Package {
}
@Collection("packages")
@Index({id: 1}, { unique: true })
@Collection('packages')
@Index({id: 1}, {unique: true})
export class PackageSchema extends Instance<Package, PackageSchema> implements Package {
@Property(String, true)
id: string;
......@@ -66,11 +66,11 @@ export class PackageSchema extends Instance<Package, PackageSchema> implements P
@Property(Array, false)
archives: Archive[];
static onCreating(pack: Package){
pack.status = pack.status || 'init'
static onCreating(pack: Package) {
pack.status = pack.status || 'init';
}
handleUpdate(data: Package) {
Object.assign(this, data)
Object.assign(this, data);
}
}
\ No newline at end of file
}
import Router = require('koa-router');
import {mongodb} from '../models/iridium'
import {App, AppSchema} from "../models/App";
import {Context} from "koa";
import {mongodb} from '../models/iridium';
import {App, AppSchema} from '../models/App';
import {Context} from 'koa';
const router = new Router();
// router.get('/apps', async (ctx: Context, next) => {
// ctx.body = await mongodb.Apps.find({})
// .map(async app => {
// if(Array.isArray(app.packages) && app.packages.length > 0){
// app.packages = await Promise.all(app.packages.map(async p => {
// try {
// return await mongodb.Packages.findOne({_id: toObjectID(p)})
// } catch (e) {
// console.log(p)
// }
// }))
// }
// return app
// })
// });
router.get('/v2/apps', async(ctx: Context, next) => {
ctx.body = await mongodb.Apps.find({}).toArray()
})
router.get('/v2/apps', async (ctx: Context, next) => {
ctx.body = await mongodb.Apps.find({}).toArray();
});
router.get('/v1/apps', async (ctx: Context, next) => {
let payload = ctx.request.query
if((!payload.author && !payload.admin)) {
ctx.throw(400, 'params error')
let payload = ctx.request.query;
if ((!payload.author && !payload.admin)) {
ctx.throw(400, 'params error');
}
let apps = {}
if(payload.admin == 'true') {
apps = await mongodb.Apps.find({}).toArray()
let apps = {};
if (payload.admin == 'true') {
apps = await mongodb.Apps.find({}).toArray();
} else {
apps = await mongodb.Apps.find({author: payload.author}).toArray()
apps = await mongodb.Apps.find({author: payload.author}).toArray();
}
ctx.body = apps
})
ctx.body = apps;
});
router.post('/v1/app/:id', async (ctx: Context, next) => {
let payload = ctx.request.body
if(!payload.id) {
ctx.throw(400, 'params error')
let payload = ctx.request.body;
if (!payload.id) {
ctx.throw(400, 'params error');
}
if (ctx.params.id !== payload.id) {
ctx.throw(400, "App is not same")
ctx.throw(400, 'App is not same');
}
let exists = await mongodb.Apps.findOne({id: payload.id});
if (exists) {
ctx.throw(400, "App is exists")
ctx.throw(400, 'App is exists');
}
try {
ctx.body = await mongodb.Apps.insert(payload)
ctx.body = await mongodb.Apps.insert(payload);
} catch (e) {
ctx.throw(400, e)
ctx.throw(400, e);
}
})
});
router.patch('/v1/app/:id', async (ctx: Context, next) => {
let _app: App = ctx.request.body
let _app: App = ctx.request.body;
let app: AppSchema | null = await mongodb.Apps.findOne({id: ctx.params.id});
if (!app) {
ctx.throw(400, `App ${ctx.params.id} Not Found `);
}
if (!ctx.request.body.id || ctx.request.body.id !== app!.id) {
ctx.throw(400, `Can not change AppID`)
ctx.throw(400, `Can not change AppID`);
}
app!.handleUpdate(_app)
app!.handleUpdate(_app);
ctx.body = await app!.save()
})
ctx.body = await app!.save();
});
export default router
\ No newline at end of file
export default router;
import Router = require('koa-router');
import {toObjectID} from 'iridium'
import {mongodb} from '../models/iridium'
import {Context} from "koa";
import config from '../../config'
import {Archive, Package} from "../models/Package";
import {renderChecksum} from "../utils";
import {toObjectID} from 'iridium';
import {mongodb} from '../models/iridium';
import {Context} from 'koa';
import config from '../../config';
import {Archive, Package} from '../models/Package';
import {renderChecksum} from '../utils';
const router = new Router();
router.get('/v2/packages', async (ctx: Context, next) => {
if (!ctx.request.query.appId) {
ctx.throw(400, "appId must be required!")
ctx.throw(400, 'appId must be required!');
}
let packs = await mongodb.Packages.find({appId: ctx.request.query.appId, status: 'uploaded'}).toArray()
let packs = await mongodb.Packages.find({
appId: ctx.request.query.appId,
status: 'uploaded'
}).toArray();
ctx.body = {
[ctx.request.query.appId]: packs
}
})
};
});
router.get('/v2/package/:id/checksum', async(ctx: Context, next) => {
let pack = await mongodb.Packages.findOne({id: ctx.params.id, status: 'uploaded'})
if(!pack) {
return ctx.throw(400, 'pack error')
router.get('/v2/package/:id/checksum', async (ctx: Context, next) => {
let pack = await mongodb.Packages.findOne({id: ctx.params.id, status: 'uploaded'});
if (!pack) {
return ctx.throw(400, 'pack error');
}
ctx.body = renderChecksum(pack.files)
})
ctx.body = renderChecksum(pack.files);
});
router.get('/v2/package/:id/meta', async(ctx: Context, next) => {
router.get('/v2/package/:id/meta', async (ctx: Context, next) => {
let pack = await mongodb.Packages.findOne({id: ctx.params.id, status: 'uploaded'})
if(!pack) {
return ctx.throw(400, 'pack error')
let pack = await mongodb.Packages.findOne({id: ctx.params.id, status: 'uploaded'});
if (!pack) {
return ctx.throw(400, 'pack error');
}
await ctx['render']('update', {files: {
name: pack.id,
size: pack.fullSize,
hash: pack.fullHash
}})
})
await ctx['render']('update', {
files: {
name: pack.id,
size: pack.fullSize,
hash: pack.fullHash
}
});
});
router.post('/v2/package/:id/update', async (ctx: Context, next) => {
const package_id = ctx.params.id
const download_path = config.download_path
const request_overhead = 1024 * 1024
let sandSize = ctx.request.body.length * request_overhead
const package_id = ctx.params.id;
const request_overhead = 1024 * 1024;
let sandSize = ctx.request.body.length * request_overhead;
let pack = await mongodb.Packages.findOne({id: package_id, status: 'uploaded'})
let {fullSize, fullPath} = pack!
let pack = await mongodb.Packages.findOne({id: package_id, status: 'uploaded'});
if (!pack) {
return ctx.throw(400, 'pack not exists');
}
let {fullSize} = pack;
let files
let fullFiles = new Map<string, Archive>()
let files;
let fullFiles = new Map<string, Archive>();
pack!.archives.map((f) => {
fullFiles.set(f.path, f)
})
pack.archives.map((f) => {
fullFiles.set(f.path, f);
});
if(fullSize > sandSize) {
if (fullSize > sandSize) {
files = ctx.request.body.map((_file) => {
const file: Archive|undefined = fullFiles.get(_file)
if(!file) {
//
}
sandSize += file.size
return {
path: file.path,
size: file.size,
hash: file.hash
}
})
}
if( sandSize <= fullSize ) {
const file: Archive | undefined = fullFiles.get(_file);
if (!file) {
return ctx.throw(400, '');
}
sandSize += file.size;
return {
path: file.path,
size: file.size,
hash: file.hash
};
});
}
if (sandSize <= fullSize) {
files = [{
path: pack.id,
size: pack.fullSize,
hash: pack.fullHash
}]
}];
}
await ctx['render']('update', {files})
})
await ctx['render']('update', {files});
});
router.get('/v1/packages', async (ctx: Context, next) => {
if (!ctx.request.query.appId) {
ctx.throw(400, "appId must be required!")
ctx.throw(400, 'appId must be required!');
}
let packs = await mongodb.Packages.find({appId: ctx.request.query.appId, type: 'editing'}).toArray()
let packs = await mongodb.Packages.find({
appId: ctx.request.query.appId,
type: 'editing'
}).toArray();
ctx.body = {
[ctx.request.query.appId]: packs
}
})
};
});
router.post('/v1/package', async (ctx: Context, next) => {
const _p: Package = ctx.request.body
const _p: Package = ctx.request.body;
if (!_p.id) {
ctx.throw(400, `id 参数缺失:${_p.id}`)
ctx.throw(400, `id 参数缺失:${_p.id}`);
}
if (!_p.platforms || _p.platforms.length == 0) {
ctx.throw(400, `请填写支持的平台:${_p.id}`)
}
else if (!_p.locales || _p.locales.length == 0) {
ctx.throw(400, `请填写支持的语言:${_p.id}`)
}
else if (!_p.version) {
ctx.throw(400, `请填写版本号:${_p.id}`)
ctx.throw(400, `请填写支持的平台:${_p.id}`);
} else if (!_p.locales || _p.locales.length == 0) {
ctx.throw(400, `请填写支持的语言:${_p.id}`);
} else if (!_p.version) {
ctx.throw(400, `请填写版本号:${_p.id}`);
}
let exists_platform = await mongodb.Packages.find({ id: {$ne: _p.id}, appId: _p.appId, platforms: { $in: _p.platforms }, type: 'editing' }).count()
if(exists_platform) {
console.log(exists_platform)
ctx.throw(400, '平台已存在')
let existsPlatform = await mongodb.Packages.find({
id: {$ne: _p.id},
appId: _p.appId,
platforms: {$in: _p.platforms},
type: 'editing'
}).count();
if (existsPlatform) {
console.log(existsPlatform);
ctx.throw(400, '平台已存在');
}
let exists_locales = await mongodb.Packages.find({ id: {$ne: _p.id}, appId: _p.appId, locales: { $in: _p.locales }, type: 'editing' }).count()
if(exists_locales) {
console.log(exists_locales)
ctx.throw(400, '语言已存在')
let existsLocales = await mongodb.Packages.find({
id: {$ne: _p.id},
appId: _p.appId,
locales: {$in: _p.locales},
type: 'editing'
}).count();
if (existsLocales) {
console.log(existsLocales);
ctx.throw(400, '语言已存在');
}
await mongodb.Packages.update({id: _p.id}, {$set: { type: 'edited' }}, {multi: true})
await mongodb.Packages.update({id: _p.id}, {$set: {type: 'edited'}}, {multi: true});
let _pack: Package = {
id: _p.id,
......@@ -134,59 +152,73 @@ router.post('/v1/package', async (ctx: Context, next) => {
platforms: _p.platforms,
status: 'init',
type: 'editing'
}
};
ctx.body = await mongodb.Packages.insert(_pack)
})
ctx.body = await mongodb.Packages.insert(_pack);
});
router.patch('/v1/package', async (ctx: Context, next) => {
const _p: Package = ctx.request.body
const p = await mongodb.Packages.findOne({_id: toObjectID(_p._id)})
const _p = ctx.request.body;
const p = await mongodb.Packages.findOne({_id: toObjectID(_p._id)});
if (!p) {
return ctx.throw(400, 'pack not exists');
}
if (!_p.id) {
ctx.throw(400, `id 参数缺失:${_p.id}`)
ctx.throw(400, `id 参数缺失:${_p.id}`);
}
if (!_p.platforms || _p.platforms.length == 0) {
ctx.throw(400, `请填写支持的平台:${_p.id}`)
}
else if (!_p.locales || _p.locales.length == 0) {
ctx.throw(400, `请填写支持的语言:${_p.id}`)
}
else if (!_p.version) {
ctx.throw(400, `请填写版本号:${_p.id}`)
ctx.throw(400, `请填写支持的平台:${_p.id}`);
} else if (!_p.locales || _p.locales.length == 0) {
ctx.throw(400, `请填写支持的语言:${_p.id}`);
} else if (!_p.version) {
ctx.throw(400, `请填写版本号:${_p.id}`);
}
let exists_platform = await mongodb.Packages.find({ id: {$ne: _p.id}, appId: _p.appId, platforms: { $in: _p.platforms }, type: 'editing' }).count()
if(exists_platform) {
console.log(exists_platform)
ctx.throw(400, '平台已存在')
let existsPlatform = await mongodb.Packages.find({
id: {$ne: _p.id},
appId: _p.appId,
platforms: {$in: _p.platforms},
type: 'editing'
}).count();
if (existsPlatform) {
console.log(existsPlatform);
ctx.throw(400, '平台已存在');
}
let exists_locales = await mongodb.Packages.find({ id: {$ne: _p.id}, appId: _p.appId, locales: { $in: _p.locales }, type: 'editing' }).count()
if(exists_locales) {
console.log(exists_locales)
ctx.throw(400, '语言已存在')
let existsLocales = await mongodb.Packages.find({
id: {$ne: _p.id},
appId: _p.appId,
locales: {$in: _p.locales},
type: 'editing'
}).count();
if (existsLocales) {
console.log(existsLocales);
ctx.throw(400, '语言已存在');
}
if (p.status == 'init') {
p.handleUpdate(_p)
ctx.body = await p.save()
p.handleUpdate(_p);
ctx.body = await p.save();
} else {
ctx.throw(400, `非法操作:${_p.id}`)
ctx.throw(400, `非法操作:${_p.id}`);
}
})
});
router.delete('/v1/package', async(ctx: Context, next) => {
const _p: Package = ctx.request.body
const p = await mongodb.Packages.findOne({_id: toObjectID(_p._id)})
router.delete('/v1/package', async (ctx: Context, next) => {
const _p = ctx.request.body;
const p = await mongodb.Packages.findOne({_id: toObjectID(_p._id)});
if (!p) {
return ctx.throw(400, 'pack not exists');
}
p.type = 'edited'
p.status = 'delete'
await p.save()
p.type = 'edited';
p.status = 'delete';
await p.save();
ctx.body = {
message: 'delete successful'
}
})
};
});
export default router
\ No newline at end of file
export default router;
......@@ -4,13 +4,13 @@ import * as busboy from 'async-busboy';
import * as mime from 'mime';
import * as uuid from 'uuid';
import * as Client from 'aliyun-oss-upload-stream';
import * as fs from 'fs-extra-promise'
import * as path from 'path'
import * as Aria2 from 'aria2'
import {bundle} from '../../package/main'
import {mongodb} from '../models/iridium'
import {toObjectID} from 'iridium'
import config from '../../config'
import * as fs from 'fs-extra-promise';
import * as path from 'path';
import * as Aria2 from 'aria2';
import {bundle} from '../../package/main';
import {mongodb} from '../models/iridium';
import {toObjectID} from 'iridium';
import config from '../../config';
// const Aria2Options = {
// host: 'localhost',
......@@ -21,29 +21,28 @@ import config from '../../config'
// }
const checkPackage = async (file) => {
// const ext = mime.extension(file.mime);
if (['zip', 'gz', 'rar', '7z', 'application/x-gzip'].indexOf(file.mime) === -1) {
throw new Error('Unsupported file type');
}
}
};
const checkImage = async (file) => {
const ext = mime.extension(file.mime);
if (['png', 'jpg', 'jpeg', 'gif', 'webp'].indexOf(ext) === -1) {
throw new Error('Unsupported file type');
}
}
};
import Router = require('koa-router');
const ossStream = Client(new OSS({
accessKeyId: process.env["OSS_ACCESS_ID"],
secretAccessKey: process.env["OSS_ACCESS_KEY"],
endpoint: process.env["OSS_ENDPOINT"],
accessKeyId: process.env['OSS_ACCESS_ID'],
secretAccessKey: process.env['OSS_ACCESS_KEY'],
endpoint: process.env['OSS_ENDPOINT'],
apiVersion: '2013-10-15'
}));
const router = new Router()
const router = new Router();
const UploadImage = async (ctx: Context) => {
......@@ -51,12 +50,12 @@ const UploadImage = async (ctx: Context) => {
const {files} = await busboy(ctx.req);
ctx.body = await Promise.all(files.map(async file => {
await checkImage(file)
await checkImage(file);
const filename = `test/${uuid.v1()}`;
const upload = ossStream.upload({
Bucket: process.env["OSS_BUCKET"],
Bucket: process.env['OSS_BUCKET'],
Key: filename,
ContentType: file.mimeType
});
......@@ -78,130 +77,136 @@ export const UploadPackage = async (ctx: Context) => {
const {files} = await busboy(ctx.req);
ctx.body = await Promise.all(files.map(async file => {
await checkPackage(file)
await checkPackage(file);
const filename = uuid.v1()
const filename = uuid.v1();
const archive_path = path.join(__dirname, '../../test/upload')
await fs.ensureDirAsync(archive_path)
const archive_path = path.join(__dirname, '../../test/upload');
await fs.ensureDirAsync(archive_path);
const archive = fs.createWriteStream(path.join(archive_path, filename))
const archive = fs.createWriteStream(path.join(archive_path, filename));
let pack = await mongodb.Packages.findOne({_id: toObjectID(ctx.params.id)})
let pack = await mongodb.Packages.findOne({_id: toObjectID(ctx.params.id)});
if (!pack) {
return ctx.throw(400, 'pack not exists');
}
return await new Promise((resolve, reject) => {
file.pipe(archive)
file.pipe(archive);
file.on('close', async() => {
file.on('close', async () => {
try {
pack.status = 'uploading'
await pack.save()
pack!.status = 'uploading';
await pack!.save();
resolve(pack)
resolve(pack!);
// 上传完, 打包
const bundled = await bundle(filename)
const bundled = await bundle(filename);
Object.assign(pack, bundled)
pack.status = 'uploaded'
Object.assign(pack, bundled);
pack!.status = 'uploaded';
await mongodb.Packages.update({id: pack.id}, {$set: { status: 'deprecated' }}, {multi: true})
await pack.save()
await mongodb.Packages.update({id: pack!.id}, {$set: {status: 'deprecated'}}, {multi: true});
await pack!.save();
// 打包完,上传阿里云
} catch (e) {
pack.status = 'failed'
await pack.save()
console.log(e)
pack!.status = 'failed';
await pack!.save();
console.log(e);
}
})
});
file.on('error', async (error) => {
pack.status = 'failed'
await pack.save()
pack!.status = 'failed';
await pack!.save();
reject(error)
})
})
reject(error);
});
});
}));
} catch (err) {
ctx.throw(403, err);
}
}
};
const uploadPackageUrl = async (ctx: Context) => {
if(!ctx.request.body.url) {
ctx.throw(400, "params error")
if (!ctx.request.body.url) {
ctx.throw(400, 'params error');
}
//testUrl: https://r.my-card.in/release/dist/0c16a3ecb115fd7cf575ccdd64f62a8f3edc635b087950e4ed4f3f781972bbfd.tar.gz
// testUrl: https://r.my-card.in/release/dist/0c16a3ecb115fd7cf575ccdd64f62a8f3edc635b087950e4ed4f3f781972bbfd.tar.gz
const downloader = new Aria2
let pack = await mongodb.Packages.findOne({_id: toObjectID(ctx.request.body._id)})
const downloader = new Aria2;
let pack = await mongodb.Packages.findOne({_id: toObjectID(ctx.request.body._id)});
if (!pack) {
return ctx.throw(400, 'pack not exists');
}
await downloader.open()
await downloader.open();
downloader.onDownloadStart = async() => {
pack.status = 'uploading'
await pack.save()
}
downloader.onDownloadStart = async () => {
pack!.status = 'uploading';
await pack!.save();
};
downloader.onDownloadComplete = async(m) => {
const { files } = await downloader.send('tellStatus', m.gid)
const [file] = files
downloader.onDownloadComplete = async (m) => {
const {files} = await downloader.send('tellStatus', m.gid);
const [file] = files;
try {
await checkPackage(file)
await checkPackage(file);
// 打包
const bundled = await bundle(path.basename(file.path))
const bundled = await bundle(path.basename(file.path));
// 打包完, 上传阿里云
Object.assign(pack, bundled)
pack.status = 'uploaded'
Object.assign(pack, bundled);
pack!.status = 'uploaded';
await mongodb.Packages.update({id: pack.id}, {$set: { status: 'deprecated' }}, {multi: true})
await pack.save()
await mongodb.Packages.update({id: pack!.id}, {$set: {status: 'deprecated'}}, {multi: true});
await pack!.save();
} catch (e) {
pack.status = 'failed'
await pack.save()
pack!.status = 'failed';
await pack!.save();
}
}
};
downloader.onDownloadError = async(err) => {
downloader.onDownloadError = async (err) => {
// console.log(await downloader.send('tellStatus', err.gid))
pack.status = 'failed'
await pack.save()
console.log(err)
}
pack!.status = 'failed';
await pack!.save();
console.log(err);
};
ctx.body = await new Promise((resolve, reject) => {
downloader.onmessage = m => {
if(m["error"]) {
reject(m["error"])
if (m['error']) {
reject(m['error']);
} else {
resolve(m)
resolve(m);
}
}
};
downloader.send('addUri', [ctx.request.body.url], {dir: config.upload_path})
})
downloader.send('addUri', [ctx.request.body.url], {dir: config.upload_path});
});
}
};
router.post('/v1/upload/image', UploadImage)
router.post('/v1/upload/image', UploadImage);
router.post('/v1/upload/package/:id', UploadPackage)
router.post('/v1/upload/package/:id', UploadPackage);
router.post('/v1/upload/packageUrl', uploadPackageUrl)
router.post('/v1/upload/packageUrl', uploadPackageUrl);
export default router
export default router;
const TYPES = {
const TYPES = {};
}
export default TYPES
\ No newline at end of file
export default TYPES;
import { URL } from 'url';
import {URL} from 'url';
export const handleImg = (img) => {
if (img) {
......@@ -12,8 +12,8 @@ export const handleImg = (img) => {
} else {
return 'https://cdn01.moecube.com/accounts/default_avatar.jpg';
}
}
};
export function renderChecksum(files: { path: string, hash?: string }[]) {
return files.map(({ path, hash }) => `${hash || ''} ${path}`).join('\n');
}
\ No newline at end of file
return files.map(({path, hash}) => `${hash || ''} ${path}`).join('\n');
}
{
"rules": {
"max-line-length": [true, 140],
"no-inferrable-types": true,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"indent": [
true,
"spaces"
],
"eofline": true,
"no-duplicate-variable": true,
"no-eval": true,
"no-arg": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-bitwise": true,
"no-unused-expression": true,
"no-var-keyword": true,
"one-line": [
true,
"check-catch",
"check-else",
"check-open-brace",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"semicolon": [true, "always"],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"curly": true,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment