Skip to content
This repository was archived by the owner on Jul 10, 2022. It is now read-only.

Commit f12cd2c

Browse files
committed
initial commit
0 parents  commit f12cd2c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1265
-0
lines changed

.github/workflows/ci.yml

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
schedule:
7+
- cron: '0 0 * * *'
8+
9+
jobs:
10+
node14:
11+
name: Node 14
12+
runs-on: ubuntu-20.04
13+
steps:
14+
- name: checkout
15+
uses: actions/checkout@v2
16+
- name: checkout node
17+
uses: actions/setup-node@v2
18+
with:
19+
node-version: '14'
20+
- run: npm install
21+
- run: npm run build
22+
- run: npm run cs
23+
- run: npm test -- --coverage --no-cache
24+
- run: npm run infection
25+
env:
26+
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
27+
node16:
28+
name: Node 16
29+
runs-on: ubuntu-20.04
30+
steps:
31+
- name: checkout
32+
uses: actions/checkout@v2
33+
- name: checkout node
34+
uses: actions/setup-node@v2
35+
with:
36+
node-version: '16'
37+
- run: npm install
38+
- run: npm run build
39+
- run: npm run cs
40+
- run: npm test -- --coverage --no-cache
41+
- run: npm run infection
42+
env:
43+
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
44+
- name: coveralls.io
45+
uses: coverallsapp/github-action@master
46+
with:
47+
github-token: ${{ secrets.GITHUB_TOKEN }}
48+
- name: sonarcloud.io
49+
uses: sonarsource/sonarcloud-github-action@master
50+
env:
51+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
coverage
2+
dist
3+
node_modules
4+
package-lock.json
5+
var
6+
7+
# stryker temp files
8+
.stryker-tmp

LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2021 Dominik Zogg
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

README.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# chubbyjs-framework-skeleton
2+
3+
[![CI](https://github.com/chubbyjs/chubbyjs-framework-skeleton/workflows/CI/badge.svg?branch=master)](https://github.com/chubbyjs/chubbyjs-framework-skeleton/actions?query=workflow%3ACI)
4+
[![Coverage Status](https://coveralls.io/repos/github/chubbyjs/chubbyjs-framework-skeleton/badge.svg?branch=master)](https://coveralls.io/github/chubbyjs/chubbyjs-framework-skeleton?branch=master)
5+
[![Infection MSI](https://badge.stryker-mutator.io/github.com/chubbyjs/chubbyjs-framework-skeleton/master)](https://dashboard.stryker-mutator.io/reports/github.com/chubbyjs/chubbyjs-framework-skeleton/master)
6+
7+
[![bugs](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=bugs)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
8+
[![code_smells](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=code_smells)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
9+
[![coverage](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=coverage)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
10+
[![duplicated_lines_density](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=duplicated_lines_density)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
11+
[![ncloc](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=ncloc)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
12+
[![sqale_rating](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
13+
[![alert_status](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=alert_status)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
14+
[![reliability_rating](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
15+
[![security_rating](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=security_rating)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
16+
[![sqale_index](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=sqale_index)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
17+
[![vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=chubbyjs_chubbyjs-framework-skeleton&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=chubbyjs_chubbyjs-framework-skeleton)
18+
19+
## Description
20+
21+
A minimal skeleton for [chubbyjs-framework][2].
22+
23+
## Requirements
24+
25+
* node: 14
26+
* [@chubbyjs/chubbyjs-framework][2]: ^1.1.7
27+
* [@chubbyjs/chubbyjs-framework-router-path-to-regexp][3]: ^1.0.1
28+
* [@chubbyjs/chubbyjs-http-message][4]: ^1.1.1
29+
* [@chubbyjs/chubbyjs-laminas-config][5]: ^1.0.2
30+
* [@chubbyjs/chubbyjs-node-psr-http-message-bridge][6]: ^1.2.1
31+
* [@chubbyjs/chubbyjs-pino-psr][7]: ^1.0.0
32+
* [commander][8]: ^8.2.0"
33+
34+
## Installation
35+
36+
```sh
37+
git clone https://github.com/chubbyjs/chubbyjs-framework-skeleton.git my-project
38+
cd my-project
39+
rm -r .git
40+
git init
41+
```
42+
43+
## Run
44+
45+
```sh
46+
npm start
47+
```
48+
49+
## Copyright
50+
51+
Dominik Zogg 2021
52+
53+
[1]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-framework-skeleton
54+
[2]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-framework
55+
[3]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-framework-router-path-to-regexp
56+
[4]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-http-message
57+
[5]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-laminas-config
58+
[6]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-node-psr-http-message-bridg
59+
[7]: https://www.npmjs.com/package/@chubbyjs/chubbyjs-pino-psr
60+
[8]: https://www.npmjs.com/package/commander

bin/console.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Command } from 'commander';
2+
import CleanDirectoriesCommand from '../src/Command/CleanDirectoriesCommand';
3+
import container from '../bootstrap/container';
4+
5+
const console = new Command();
6+
7+
console
8+
.command('clean-directories [directoryNames]')
9+
.description('Delete everything within a given directory.')
10+
.option('-e, --env [env]', 'Environment', 'dev')
11+
.action((directoryNamesAsString: string, options: { env: string }) => {
12+
container(options.env)
13+
.get<CleanDirectoriesCommand>(CleanDirectoriesCommand.name)
14+
.clean(directoryNamesAsString.split(',').map((directoryName) => directoryName.trim()));
15+
});
16+
17+
console.parse(process.argv);

bootstrap/container.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import LaminasConfig from '@chubbyjs/chubbyjs-laminas-config/dist/Config';
2+
import LaminasContainerFactory from '@chubbyjs/chubbyjs-laminas-config/dist/ContainerFactory';
3+
import ContainerInterface from '@chubbyjs/psr-container/dist/ContainerInterface';
4+
import { existsSync, mkdirSync } from 'fs';
5+
import { Config } from '../config/prod';
6+
7+
export default (env: string): ContainerInterface => {
8+
const config: Config = require(`../config/${env}`).default(env);
9+
10+
config.directories.forEach((directory) => {
11+
if (!existsSync(directory)) {
12+
mkdirSync(directory, { recursive: true });
13+
}
14+
});
15+
16+
return LaminasContainerFactory(new LaminasConfig(config));
17+
};

config/dev.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import prod, { Config } from './prod';
2+
3+
export default (env: string): Config => {
4+
const config = prod(env);
5+
6+
return {
7+
...config,
8+
debug: true,
9+
pino: {
10+
...config.pino,
11+
options: {
12+
...config.pino.options,
13+
level: 'debug',
14+
}
15+
}
16+
};
17+
};

config/jest.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import dev from './dev';
2+
import { Config } from './prod';
3+
4+
export default (env: string): Config => {
5+
return dev(env);
6+
};

config/prod.ts

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import PathToRegexpRouteMatcher from "@chubbyjs/chubbyjs-framework-router-path-to-regexp/dist/PathToRegexpRouteMatcher";
2+
import PathToRegexpUrlGenerator from "@chubbyjs/chubbyjs-framework-router-path-to-regexp/dist/PathToRegexpUrlGenerator";
3+
import ErrorMiddleware from "@chubbyjs/chubbyjs-framework/dist/Middleware/ErrorMiddleware";
4+
import RouteMatcherMiddleware from "@chubbyjs/chubbyjs-framework/dist/Middleware/RouteMatcherMiddleware";
5+
import ResponseFactory from "@chubbyjs/chubbyjs-http-message/dist/Factory/ResponseFactory";
6+
import LaminasFactoryInterface from "@chubbyjs/chubbyjs-laminas-config/dist/LaminasFactoryInterface";
7+
import PinoPsrLogger from "@chubbyjs/chubbyjs-pino-psr/dist/PinoPsrLogger";
8+
import { createWriteStream, realpathSync, WriteStream } from "fs";
9+
import { DestinationStream, LoggerOptions } from 'pino';
10+
import CleanDirectoriesCommand from "../src/Command/CleanDirectoriesCommand";
11+
import PingRequestHandler from "../src/RequestHandler/PingRequestHandler";
12+
import CleanDirectoriesCommandFactory from "../src/ServiceFactory/Command/CleanDirectoriesCommandFactory";
13+
import ErrorMiddlewareFactory from "../src/ServiceFactory/Framework/ErrorMiddlewareFactory";
14+
import MiddlewaresFactory from "../src/ServiceFactory/Framework/MiddlewaresFactory";
15+
import PathToRegexpRouteMatcherFactory from "../src/ServiceFactory/Framework/PathToRegexpRouteMatcherFactory";
16+
import PathToRegexpUrlGeneratorFactory from "../src/ServiceFactory/Framework/PathToRegexpUrlGeneratorFactory";
17+
import RouteMatcherMiddlewareFactory from "../src/ServiceFactory/Framework/RouteMatcherMiddlewareFactory";
18+
import RoutesFactory from "../src/ServiceFactory/Framework/RoutesFactory";
19+
import ResponseFactoryFactory from "../src/ServiceFactory/Http/ResponseFactoryFactory";
20+
import PinoPsrLoggerFactory from "../src/ServiceFactory/Logger/PinoPsrLoggerFactory";
21+
import PingRequestHandlerFactory from "../src/ServiceFactory/RequestHandler/PingRequestHandlerFactory";
22+
23+
export type Config = {
24+
debug: boolean,
25+
dependencies: {
26+
factories: Map<string, LaminasFactoryInterface>,
27+
};
28+
directories: Map<string, string>,
29+
pino: {
30+
options: Omit<LoggerOptions, 'level'> & { level: 'fatal' | 'error' | 'warn' | 'info' | 'debug'; },
31+
stream: DestinationStream,
32+
},
33+
};
34+
35+
const rootDir = realpathSync(__dirname + '/..');
36+
37+
export default (env: string): Config => {
38+
const cacheDir = rootDir + '/var/cache/' + env;
39+
const logDir = rootDir + '/var/log';
40+
41+
let logStream: WriteStream | undefined;
42+
43+
return {
44+
debug: false,
45+
dependencies: {
46+
factories: new Map<string, LaminasFactoryInterface>([
47+
['Middleware[]', MiddlewaresFactory],
48+
['Routes', RoutesFactory],
49+
[CleanDirectoriesCommand.name, CleanDirectoriesCommandFactory],
50+
[ErrorMiddleware.name, ErrorMiddlewareFactory],
51+
[PathToRegexpRouteMatcher.name, PathToRegexpRouteMatcherFactory],
52+
[PathToRegexpUrlGenerator.name, PathToRegexpUrlGeneratorFactory],
53+
[PingRequestHandler.name, PingRequestHandlerFactory],
54+
[PinoPsrLogger.name, PinoPsrLoggerFactory],
55+
[ResponseFactory.name, ResponseFactoryFactory],
56+
[RouteMatcherMiddleware.name, RouteMatcherMiddlewareFactory],
57+
]),
58+
},
59+
directories: new Map([
60+
['cache', cacheDir],
61+
['log', logDir],
62+
]),
63+
pino: {
64+
options: {
65+
name: 'chubbyjs-framework-skeleton',
66+
level: 'info',
67+
},
68+
stream: {
69+
write: (msg: string): void => {
70+
if (!logStream) {
71+
logStream = createWriteStream(logDir + '/' + env + '.log', { flags: 'a' });
72+
}
73+
74+
logStream.write(msg);
75+
}
76+
},
77+
},
78+
};
79+
};

package.json

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"name": "@chubbyjs/chubbyjs-framework-skeleton",
3+
"version": "1.0.0",
4+
"description": "A minimal skeleton for chubbyjs-framework.",
5+
"keywords": [
6+
"chubbyjs",
7+
"framework",
8+
"skleton"
9+
],
10+
"author": "Dominik Zogg",
11+
"license": "MIT",
12+
"repository": "chubbyjs/chubbyjs-framework-skeleton",
13+
"scripts": {
14+
"cs-fix": "prettier --write src tests",
15+
"cs": "prettier --check src tests",
16+
"test": "jest",
17+
"infection": "stryker run",
18+
"build": "tsc",
19+
"prepare": "rm -Rf dist && npm run build && npm run cs && npm run test",
20+
"start": "tsc-watch --onSuccess \"node ./dist/public/index.js\""
21+
},
22+
"jest": {
23+
"preset": "ts-jest",
24+
"testEnvironment": "node",
25+
"collectCoverageFrom": [
26+
"src/**/*.ts"
27+
],
28+
"coverageThreshold": {
29+
"global": {
30+
"lines": 100
31+
}
32+
}
33+
},
34+
"prettier": {
35+
"printWidth": 120,
36+
"tabWidth": 4,
37+
"singleQuote": true,
38+
"trailingComma": "all"
39+
},
40+
"files": [
41+
"dist"
42+
],
43+
"engines": {
44+
"node": ">=14"
45+
},
46+
"dependencies": {
47+
"@chubbyjs/chubbyjs-framework-router-path-to-regexp": "^1.0.1",
48+
"@chubbyjs/chubbyjs-framework": "^1.1.7",
49+
"@chubbyjs/chubbyjs-http-message": "^1.1.1",
50+
"@chubbyjs/chubbyjs-laminas-config": "^1.0.2",
51+
"@chubbyjs/chubbyjs-node-psr-http-message-bridge": "^1.2.1",
52+
"@chubbyjs/chubbyjs-pino-psr": "^1.0.0",
53+
"@types/commander": "^2.12.2",
54+
"@types/node": "^14",
55+
"commander": "^8.2.0"
56+
},
57+
"devDependencies": {
58+
"@chubbyjs/chubbyjs-mock": "^1.1.1",
59+
"@stryker-mutator/core": "^5.3.0",
60+
"@stryker-mutator/jest-runner": "^5.3.0",
61+
"@types/jest": "^27.0.1",
62+
"jest": "^27.1.0",
63+
"prettier": "2.3.2",
64+
"ts-jest": "^27.0.5",
65+
"ts-node": "^10.2.1",
66+
"tsc-watch": "^4.5.0",
67+
"typescript": "^4.4.2"
68+
},
69+
"publishConfig": {
70+
"access": "public"
71+
}
72+
}

public/index.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Application from '@chubbyjs/chubbyjs-framework/dist/Application';
2+
import ServerRequestFactory from '@chubbyjs/chubbyjs-http-message/dist/Factory/ServerRequestFactory';
3+
import StreamFactory from '@chubbyjs/chubbyjs-http-message/dist/Factory/StreamFactory';
4+
import UriFactory from '@chubbyjs/chubbyjs-http-message/dist/Factory/UriFactory';
5+
import NodeResponseEmitter from '@chubbyjs/chubbyjs-node-psr-http-message-bridge/dist/NodeResponseEmitter';
6+
import PsrRequestFactory from '@chubbyjs/chubbyjs-node-psr-http-message-bridge/dist/PsrRequestFactory';
7+
import MiddlewareInterface from '@chubbyjs/psr-http-server-middleware/dist/MiddlewareInterface';
8+
import { createServer, IncomingMessage, ServerResponse } from 'http';
9+
import container from '../bootstrap/container';
10+
11+
const app = new Application(container(process.env.APP_ENV ?? 'dev').get<Array<MiddlewareInterface>>('Middleware[]'));
12+
13+
const psrRequestFactory = new PsrRequestFactory(
14+
new ServerRequestFactory(),
15+
new UriFactory(),
16+
new StreamFactory(),
17+
);
18+
19+
const nodeResponseEmitter = new NodeResponseEmitter();
20+
21+
const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {
22+
const serverRequest = psrRequestFactory.create(req);
23+
const response = await app.handle(serverRequest);
24+
25+
nodeResponseEmitter.emit(response, res);
26+
});
27+
28+
server.listen(8080);

sonar-project.properties

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
sonar.organization=chubbyjs
2+
sonar.projectKey=chubbyjs_chubbyjs-framework-skeleton
3+
sonar.projectName=chubbyjs-framework-skeleton
4+
5+
sonar.sources=src
6+
sonar.tests=tests
7+
sonar.language=typescript
8+
sonar.sourceEncoding=UTF-8
9+
sonar.javascript.lcov.reportPaths=coverage/lcov.info

0 commit comments

Comments
 (0)