Skip to content

Commit

Permalink
Init project structure
Browse files Browse the repository at this point in the history
  • Loading branch information
killagu committed Sep 9, 2021
1 parent 834aa03 commit eaa7b61
Show file tree
Hide file tree
Showing 34 changed files with 906 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
app/proxy*
**/*.d.ts
node_modules/
dist/
coverage/
mocks/
.react_entries/
6 changes: 6 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "eslint-config-egg/typescript",
"rules": {

}
}
52 changes: 52 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
schedule:
- cron: '0 2 * * *'

jobs:
build:
runs-on: ${{ matrix.os }}

services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: cnpmjs_test
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5

strategy:
fail-fast: false
matrix:
node-version: [14]
os: [ubuntu-latest]

steps:
- name: Checkout Git Source
uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Install Dependencies
run: npm i -g npminstall && npminstall

- name: Continuous Integration
run: npm run ci

- name: Code Coverage
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
41 changes: 41 additions & 0 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 如何共享 cnpmcore

## 项目结构

```
app
├── common
│ └── adapter
├── core
│ ├── entity
│ ├── events
│ ├── service
│ └── util
├── port
│ └── controller
├── repository
│ └── model
└── test
├── control
│ └── response_time.test.js
└── controller
└── home.test.js
```

common:
- util:全局工具类
- adapter:外部服务调用

core:
- entity:核心模型,实现业务行为
- events:异步事件定义,以及消费,串联业务
- service:核心业务
- util:服务 core 内部,不对外暴露

repository:
- model:ORM 模型,数据定义
- XXXRepository: 仓储接口,存储、查询过程

port:
- controller:HTTP controller

Empty file added app/common/adapter/.gitkeep
Empty file.
32 changes: 32 additions & 0 deletions app/core/entity/Dist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Entity, EntityData } from './Entity';
import { EasyData, EntityUtil } from '../util/EntityUtil';

export interface DistData extends EntityData {
distId: string;
name: string;
path: string;
size: number;
shasum: string;
}

export class Dist extends Entity {
readonly distId: string;
readonly name: string;
readonly path: string;
readonly size: number;
readonly shasum: string;

constructor(data: DistData) {
super(data);
this.distId = data.distId;
this.name = data.name;
this.path = data.path;
this.size = data.size;
this.shasum = data.shasum;
}

static create(data: EasyData<DistData, 'distId'>): Dist {
const newData = EntityUtil.defaultData(data, 'distId');
return new Dist(newData);
}
}
18 changes: 18 additions & 0 deletions app/core/entity/Entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface EntityData {
id?: bigint;
gmtModified: Date;
gmtCreate: Date;
}

export class Entity {
id?: bigint;
gmtModified: Date;

readonly gmtCreate: Date;

constructor(data: EntityData) {
this.id = data.id;
this.gmtCreate = data.gmtCreate;
this.gmtModified = data.gmtModified;
}
}
70 changes: 70 additions & 0 deletions app/core/entity/Package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import path from 'path';
import { Entity, EntityData } from './Entity';
import { EasyData, EntityUtil } from '../util/EntityUtil';
import { Dist } from './Dist';

export interface PackageData extends EntityData {
scope?: string;
name: string;
packageId: string;
isPrivate: boolean;
}

export enum DIST_NAMES {
MANIFEST = 'package.json',
README = 'readme.md',
TAR = '.tar.gz',
}

interface FileInfo {
size: number;
shasum: string;
}

export class Package extends Entity {
readonly scope?: string;
readonly name: string;
readonly packageId: string;
readonly isPrivate: boolean;

constructor(data: PackageData) {
super(data);
this.scope = data.scope;
this.name = data.name;
this.packageId = data.packageId;
this.isPrivate = data.isPrivate;
}

static create(data: EasyData<PackageData, 'packageId'>): Package {
const newData = EntityUtil.defaultData(data, 'packageId');
return new Package(newData);
}

distDir(version: string) {
if (this.scope) {
return `/packages/${this.scope}/${this.name}/${version}/`;
}
return `/packages/${this.name}/${version}/`;
}

private createDist(version: string, name: string, info: FileInfo) {
return Dist.create({
name,
size: info.size,
shasum: info.shasum,
path: path.join(this.distDir(version), name),
});
}

createManifest(version: string, info: FileInfo) {
return this.createDist(version, DIST_NAMES.MANIFEST, info);
}

createReadme(version: string, info: FileInfo) {
return this.createDist(version, DIST_NAMES.README, info);
}

createTar(version: string, info: FileInfo) {
return this.createDist(version, `${this.name}-${version}${DIST_NAMES.TAR}`, info);
}
}
39 changes: 39 additions & 0 deletions app/core/entity/PackageVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Dist } from './Dist';
import { Entity, EntityData } from './Entity';
import { EasyData, EntityUtil } from '../util/EntityUtil';

export interface PackageVersionData extends EntityData {
packageId: string;
packageVersionId: string;
version: string;
manifestDist: Dist;
tarDist: Dist;
readmeDist: Dist;
publishTime: Date;
}

export class PackageVersion extends Entity {
packageId: string;
packageVersionId: string;
version: string;
manifestDist: Dist;
tarDist: Dist;
readmeDist: Dist;
publishTime: Date;

constructor(data: PackageVersionData) {
super(data);
this.packageId = data.packageId;
this.packageVersionId = data.packageVersionId;
this.version = data.version;
this.manifestDist = data.manifestDist;
this.tarDist = data.tarDist;
this.readmeDist = data.readmeDist;
this.publishTime = data.publishTime;
}

static create(data: EasyData<PackageVersionData, 'packageVersionId'>): PackageVersion {
const newData = EntityUtil.defaultData(data, 'packageVersionId');
return new PackageVersion(newData);
}
}
9 changes: 9 additions & 0 deletions app/core/events/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '@eggjs/tegg';

export const PACKAGE_PUBLISHED = 'PACKAGE_PUBLISHED';

declare module '@eggjs/tegg' {
interface Events {
[PACKAGE_PUBLISHED]: (packageVersionId: string) => Promise<void>;
}
}
6 changes: 6 additions & 0 deletions app/core/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "cnpmcore-core",
"eggModule": {
"name": "cnpmcoreCore"
}
}
53 changes: 53 additions & 0 deletions app/core/service/PackageManagerService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { AccessLevel, ContextProto, EventBus, Inject } from '@eggjs/tegg';
import { PackageRepository } from '../../repository/PackageRepository';
import { Package } from '../entity/Package';
import { PackageVersion } from '../entity/PackageVersion';
import { PACKAGE_PUBLISHED } from '../events';

export interface PublishPackageCmd {
// maintainer: Maintainer;
name: string;
version: string;
distTag: string;
packageJson: object;
dist: Buffer;
}

@ContextProto({
accessLevel: AccessLevel.PUBLIC,
})
export class PackageManagerService {
@Inject()
private readonly eventBus: EventBus;

@Inject()
private readonly packageRepository: PackageRepository;

async publish(cmd: PublishPackageCmd) {
const pkg = Package.create({
name: cmd.name,
isPrivate: true,
});
await this.packageRepository.createPackage(pkg);
const pkgVersion = PackageVersion.create({
packageId: pkg.packageId,
publishTime: new Date(),
manifestDist: pkg.createManifest(cmd.version, {
size: 0,
shasum: '',
}),
readmeDist: pkg.createReadme(cmd.version, {
size: 0,
shasum: '',
}),
tarDist: pkg.createTar(cmd.version, {
size: 0,
shasum: '',
}),
version: cmd.version,
});
await this.packageRepository.createPackageVersion(pkgVersion);
this.eventBus.emit(PACKAGE_PUBLISHED, pkgVersion.packageVersionId);
return pkgVersion.packageVersionId;
}
}
20 changes: 20 additions & 0 deletions app/core/util/EntityUtil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { EntityData } from '../entity/Entity';
import ObjectID from 'bson-objectid';

type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

export type EasyData<T extends EntityData, Id extends keyof T> = PartialBy<T, 'gmtCreate' | 'gmtModified' | Id>;


export class EntityUtil {
static defaultData<T extends EntityData, Id extends keyof T>(data: EasyData<T, Id>, id: Id): T {
Reflect.set(data, id, EntityUtil.createId());
data.gmtCreate = data.gmtCreate || new Date();
data.gmtModified = data.gmtModified || new Date();
return data as T;
}

static createId(): string {
return new ObjectID().toHexString();
}
}
16 changes: 16 additions & 0 deletions app/port/controller/PackageController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam, Inject } from '@eggjs/tegg';
import { PackageRepository } from '../../repository/PackageRepository';

@HTTPController()
export class PackageController {
@Inject()
private packageRepository: PackageRepository;

@HTTPMethod({
path: '/:name/:version',
method: HTTPMethodEnum.GET,
})
async showVersion(@HTTPParam() name: string, @HTTPParam() version: string) {
return this.packageRepository.findPackageVersion(null, name, version);
}
}
6 changes: 6 additions & 0 deletions app/port/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "cnpmcore-port",
"eggModule": {
"name": "cnpmcorePort"
}
}
Loading

0 comments on commit eaa7b61

Please sign in to comment.