yxorp 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,113 +1,113 @@
1
- import { Service } from 'typedi';
2
- import { ServerResponse, IncomingMessage } from 'http';
3
- import path from 'path';
4
- import fs from 'fs/promises';
5
- import mime from 'mime';
6
- import { Dirent } from 'fs';
7
- import { Config } from '../services/config.service';
8
- import { Middleware } from '../services/pipeline.service';
9
- import { LoggerService } from '../services/logger.service';
10
-
11
-
12
- @Service({
13
- global: true
14
- })
15
- export class StaticMiddleware implements Middleware<[req: IncomingMessage, res: ServerResponse]> {
16
- constructor(
17
- private config: Config,
18
- private logger: LoggerService,
19
- ) {
20
- }
21
-
22
- public async use(req: IncomingMessage, res: ServerResponse, next: () => void): Promise<void> {
23
- try {
24
- const staticRules = this.config.get().staticRules || [];
25
-
26
- const url = new URL(req.url || '', 'http://fake.com');
27
- const urlPath = url.pathname;
28
-
29
- if (!staticRules) {
30
- next();
31
- return;
32
- }
33
-
34
- const currentStaticRule = staticRules.filter((staticRule) => {
35
- return urlPath.startsWith(staticRule.path);
36
- })[0];
37
-
38
- if (!currentStaticRule) {
39
- next();
40
- return;
41
- }
42
-
43
- const pathToDirectory = path.resolve(currentStaticRule.directory);
44
-
45
- const dirents = await this.readdir(pathToDirectory);
46
-
47
- const filePath = dirents
48
- .filter(dirent => !dirent.isDirectory())
49
- .map(dirent => ({
50
- urlPath: path.join(
51
- currentStaticRule.path,
52
- path.join(dirent.path, dirent.name).replace(pathToDirectory, '')
53
- ).replace(/\\/g, '/'),
54
- path: path.join(dirent.path, dirent.name).replace(/\\/g, '/'),
55
- }
56
- ))
57
- .filter(dirent => {
58
- const pathname = path.extname(urlPath)
59
- ? urlPath
60
- : path.join(urlPath, currentStaticRule.directoryIndex || '').replace(/\\/g, '/');
61
-
62
- if (currentStaticRule.caseInsensitive) {
63
- return dirent.urlPath.toLocaleLowerCase() === pathname.toLowerCase();
64
- } else {
65
- return dirent.urlPath === pathname;
66
- }
67
- })
68
- .map(dirent => dirent.path)[0];
69
-
70
-
71
- if (!filePath) {
72
- next();
73
- return;
74
- }
75
-
76
- const file = await fs.readFile(path.resolve(filePath));
77
- const mimeType = mime.getType(path.resolve(filePath));
78
-
79
- if (mimeType) {
80
- res.setHeader('content-type', mimeType);
81
- }
82
-
83
- res.setHeader('content-length', file.length);
84
- res.end(file);
85
-
86
- this.logger.info(`[STATIC] ${req.url}`);
87
- } catch (e) {
88
- this.logger.error(e);
89
- next();
90
- }
91
- }
92
-
93
- private async readdir(pathname: string, subpathname?: string): Promise<Dirent[]> {
94
- const files: Dirent[] = [];
95
- const fullpath = path.join(pathname, subpathname || '');
96
-
97
- const dirents = await fs.readdir(fullpath, {
98
- withFileTypes: true,
99
- });
100
-
101
- for (let dirent of dirents) {
102
- dirent.path = fullpath;
103
- files.push(dirent);
104
-
105
- if (dirent.isDirectory()) {
106
- files.push(...await this.readdir(fullpath, dirent.name));
107
- }
108
- }
109
-
110
- return files;
111
- }
112
-
113
- }
1
+ import { Service } from 'typedi';
2
+ import { ServerResponse, IncomingMessage } from 'http';
3
+ import path from 'path';
4
+ import fs from 'fs/promises';
5
+ import mime from 'mime';
6
+ import { Dirent } from 'fs';
7
+ import { Config } from '../services/config.service';
8
+ import { Middleware } from '../services/pipeline.service';
9
+ import { LoggerService } from '../services/logger.service';
10
+
11
+
12
+ @Service({
13
+ global: true
14
+ })
15
+ export class StaticMiddleware implements Middleware<[req: IncomingMessage, res: ServerResponse]> {
16
+ constructor(
17
+ private config: Config,
18
+ private logger: LoggerService,
19
+ ) {
20
+ }
21
+
22
+ public async use(req: IncomingMessage, res: ServerResponse, next: () => void): Promise<void> {
23
+ try {
24
+ const staticRules = this.config.get().staticRules || [];
25
+
26
+ const url = new URL(req.url || '', 'http://fake.com');
27
+ const urlPath = url.pathname;
28
+
29
+ if (!staticRules) {
30
+ next();
31
+ return;
32
+ }
33
+
34
+ const currentStaticRule = staticRules.filter((staticRule) => {
35
+ return urlPath.startsWith(staticRule.path);
36
+ })[0];
37
+
38
+ if (!currentStaticRule) {
39
+ next();
40
+ return;
41
+ }
42
+
43
+ const pathToDirectory = path.resolve(currentStaticRule.directory);
44
+
45
+ const dirents = await this.readdir(pathToDirectory);
46
+
47
+ const filePath = dirents
48
+ .filter(dirent => !dirent.isDirectory())
49
+ .map(dirent => ({
50
+ urlPath: path.join(
51
+ currentStaticRule.path,
52
+ path.join(dirent.path, dirent.name).replace(pathToDirectory, '')
53
+ ).replace(/\\/g, '/'),
54
+ path: path.join(dirent.path, dirent.name).replace(/\\/g, '/'),
55
+ }
56
+ ))
57
+ .filter(dirent => {
58
+ const pathname = path.extname(urlPath)
59
+ ? urlPath
60
+ : path.join(urlPath, currentStaticRule.directoryIndex || '').replace(/\\/g, '/');
61
+
62
+ if (currentStaticRule.caseInsensitive) {
63
+ return dirent.urlPath.toLocaleLowerCase() === pathname.toLowerCase();
64
+ } else {
65
+ return dirent.urlPath === pathname;
66
+ }
67
+ })
68
+ .map(dirent => dirent.path)[0];
69
+
70
+
71
+ if (!filePath) {
72
+ next();
73
+ return;
74
+ }
75
+
76
+ const file = await fs.readFile(path.resolve(filePath));
77
+ const mimeType = mime.getType(path.resolve(filePath));
78
+
79
+ if (mimeType) {
80
+ res.setHeader('content-type', mimeType);
81
+ }
82
+
83
+ res.setHeader('content-length', file.length);
84
+ res.end(file);
85
+
86
+ this.logger.info(`[STATIC] ${req.url}`);
87
+ } catch (e) {
88
+ this.logger.error(e);
89
+ next();
90
+ }
91
+ }
92
+
93
+ private async readdir(pathname: string, subpathname?: string): Promise<Dirent[]> {
94
+ const files: Dirent[] = [];
95
+ const fullpath = path.join(pathname, subpathname || '');
96
+
97
+ const dirents = await fs.readdir(fullpath, {
98
+ withFileTypes: true,
99
+ });
100
+
101
+ for (let dirent of dirents) {
102
+ dirent.path = fullpath;
103
+ files.push(dirent);
104
+
105
+ if (dirent.isDirectory()) {
106
+ files.push(...await this.readdir(fullpath, dirent.name));
107
+ }
108
+ }
109
+
110
+ return files;
111
+ }
112
+
113
+ }
@@ -1,26 +1,26 @@
1
- import { Service, Token, Inject } from 'typedi';
2
- import { YxorpConfig } from "../types/yxorp-config";
3
-
4
-
5
- export const ProxyConfigToken = new Token<YxorpConfig>('ProxyConfigToken');
6
-
7
- @Service({
8
- global: true
9
- })
10
- export class Config {
11
- private config!: YxorpConfig;
12
-
13
- constructor(
14
- @Inject(ProxyConfigToken) private proxyConfig: YxorpConfig,
15
- ) {
16
- this.config = this.proxyConfig;
17
- }
18
-
19
- public set(config: YxorpConfig): void {
20
- this.config = config;
21
- }
22
-
23
- public get(): YxorpConfig {
24
- return this.config;
25
- }
26
- }
1
+ import { Service, Token, Inject } from 'typedi';
2
+ import { YxorpConfig } from "../types/yxorp-config";
3
+
4
+
5
+ export const ProxyConfigToken = new Token<YxorpConfig>('ProxyConfigToken');
6
+
7
+ @Service({
8
+ global: true
9
+ })
10
+ export class Config {
11
+ private config!: YxorpConfig;
12
+
13
+ constructor(
14
+ @Inject(ProxyConfigToken) private proxyConfig: YxorpConfig,
15
+ ) {
16
+ this.config = this.proxyConfig;
17
+ }
18
+
19
+ public set(config: YxorpConfig): void {
20
+ this.config = config;
21
+ }
22
+
23
+ public get(): YxorpConfig {
24
+ return this.config;
25
+ }
26
+ }
@@ -1,25 +1,25 @@
1
- import { Service } from 'typedi';
2
- import { IncomingMessage, ServerResponse} from 'http';
3
- import httpProxy from 'http-proxy';
4
- import { Pipeline } from "./pipeline.service";
5
-
6
- @Service({
7
- global: true
8
- })
9
- export class HttpProxy {
10
- private httpProxy = httpProxy.createProxyServer({});
11
-
12
- constructor(
13
- private pipeline: Pipeline<[proxyRes: IncomingMessage, req: IncomingMessage, res: ServerResponse]>,
14
- ) {
15
- }
16
-
17
- public use = this.pipeline.use.bind(this.pipeline);
18
- public execute = this.pipeline.execute.bind(this.pipeline);
19
- public on = this.httpProxy.on.bind(this.httpProxy);
20
- public addListener = this.httpProxy.addListener.bind(this.httpProxy);
21
- public removeListener = this.httpProxy.removeListener.bind(this.httpProxy);
22
- public web = this.httpProxy.web.bind(this.httpProxy);
23
- public ws = this.httpProxy.ws.bind(this.httpProxy);
24
-
25
- }
1
+ import { Service } from 'typedi';
2
+ import { IncomingMessage, ServerResponse} from 'http';
3
+ import httpProxy from 'http-proxy';
4
+ import { Pipeline } from "./pipeline.service";
5
+
6
+ @Service({
7
+ global: true
8
+ })
9
+ export class HttpProxy {
10
+ private httpProxy = httpProxy.createProxyServer({});
11
+
12
+ constructor(
13
+ private pipeline: Pipeline<[proxyRes: IncomingMessage, req: IncomingMessage, res: ServerResponse]>,
14
+ ) {
15
+ }
16
+
17
+ public use = this.pipeline.use.bind(this.pipeline);
18
+ public execute = this.pipeline.execute.bind(this.pipeline);
19
+ public on = this.httpProxy.on.bind(this.httpProxy);
20
+ public addListener = this.httpProxy.addListener.bind(this.httpProxy);
21
+ public removeListener = this.httpProxy.removeListener.bind(this.httpProxy);
22
+ public web = this.httpProxy.web.bind(this.httpProxy);
23
+ public ws = this.httpProxy.ws.bind(this.httpProxy);
24
+
25
+ }
@@ -1,24 +1,24 @@
1
- import { Service } from 'typedi';
2
- import http, { IncomingMessage, Server, ServerResponse} from 'http';
3
- import { Pipeline } from './pipeline.service';
4
-
5
- @Service({
6
- global: true
7
- })
8
- export class HttpServer {
9
- private server: Server = http.createServer((req: IncomingMessage, res: ServerResponse) => {
10
- this.pipeline.execute(req, res);
11
- });
12
-
13
- constructor(
14
- private pipeline: Pipeline<[req: IncomingMessage, res: ServerResponse]>,
15
- ) {
16
- }
17
-
18
- public use = this.pipeline.use.bind(this.pipeline);
19
- public on = this.server.on.bind(this.server);
20
- public addListener = this.server.addListener.bind(this.server);
21
- public removeListener = this.server.removeListener.bind(this.server);
22
- public listen = this.server.listen.bind(this.server);
23
-
24
- }
1
+ import { Service } from 'typedi';
2
+ import http, { IncomingMessage, Server, ServerResponse} from 'http';
3
+ import { Pipeline } from './pipeline.service';
4
+
5
+ @Service({
6
+ global: true
7
+ })
8
+ export class HttpServer {
9
+ private server: Server = http.createServer((req: IncomingMessage, res: ServerResponse) => {
10
+ this.pipeline.execute(req, res);
11
+ });
12
+
13
+ constructor(
14
+ private pipeline: Pipeline<[req: IncomingMessage, res: ServerResponse]>,
15
+ ) {
16
+ }
17
+
18
+ public use = this.pipeline.use.bind(this.pipeline);
19
+ public on = this.server.on.bind(this.server);
20
+ public addListener = this.server.addListener.bind(this.server);
21
+ public removeListener = this.server.removeListener.bind(this.server);
22
+ public listen = this.server.listen.bind(this.server);
23
+
24
+ }
@@ -1,21 +1,21 @@
1
- import { Service } from 'typedi';
2
- import { createLogger, format, transports } from 'winston';
3
-
4
-
5
- @Service({
6
- global: true
7
- })
8
- export class LoggerService {
9
- private logger = createLogger({
10
- format: format.combine(
11
- format.colorize(),
12
- format.simple(),
13
- ),
14
- transports: [new transports.Console],
15
- });
16
-
17
- public info = this.logger.info.bind(this.logger);
18
- public error = this.logger.error.bind(this.logger);
19
- public warn = this.logger.warn.bind(this.logger);
20
- public debug = this.logger.debug.bind(this.logger);
21
- }
1
+ import { Service } from 'typedi';
2
+ import { createLogger, format, transports } from 'winston';
3
+
4
+
5
+ @Service({
6
+ global: true
7
+ })
8
+ export class LoggerService {
9
+ private logger = createLogger({
10
+ format: format.combine(
11
+ format.colorize(),
12
+ format.simple(),
13
+ ),
14
+ transports: [new transports.Console],
15
+ });
16
+
17
+ public info = this.logger.info.bind(this.logger);
18
+ public error = this.logger.error.bind(this.logger);
19
+ public warn = this.logger.warn.bind(this.logger);
20
+ public debug = this.logger.debug.bind(this.logger);
21
+ }
@@ -1,44 +1,44 @@
1
- import { Container, Service } from 'typedi';
2
-
3
-
4
- export interface Middleware<T extends any[]> {
5
- use(...args: [...T, () => void]): void;
6
- [k: string]: any;
7
- }
8
-
9
- export interface MiddlewareCtor<T extends any[]> {
10
- new(...args: any): Middleware<T>;
11
- }
12
- export type Middlewares<T extends any[]> = MiddlewareCtor<T>[];
13
-
14
- @Service({
15
- transient: true,
16
- })
17
- export class Pipeline<T extends any[]> {
18
- private stack: Middlewares<T> = [];
19
-
20
- public use(...middlewares: Middlewares<T>) {
21
- this.stack.push(...middlewares);
22
- }
23
-
24
- public async execute(...args: [...T]) {
25
- let prevIndex = -1;
26
-
27
- const runner = async (index: number) => {
28
- if (index === prevIndex) {
29
- throw new Error('next() called multiple times');
30
- }
31
-
32
- prevIndex = index;
33
-
34
- const middleware = Container.get(this.stack[index]);
35
-
36
- await middleware.use(...args, () => {
37
- return runner(index + 1);
38
- });
39
- }
40
-
41
- await runner(0);
42
- }
43
-
44
- }
1
+ import { Container, Service } from 'typedi';
2
+
3
+
4
+ export interface Middleware<T extends any[]> {
5
+ use(...args: [...T, () => void]): void;
6
+ [k: string]: any;
7
+ }
8
+
9
+ export interface MiddlewareCtor<T extends any[]> {
10
+ new(...args: any): Middleware<T>;
11
+ }
12
+ export type Middlewares<T extends any[]> = MiddlewareCtor<T>[];
13
+
14
+ @Service({
15
+ transient: true,
16
+ })
17
+ export class Pipeline<T extends any[]> {
18
+ private stack: Middlewares<T> = [];
19
+
20
+ public use(...middlewares: Middlewares<T>) {
21
+ this.stack.push(...middlewares);
22
+ }
23
+
24
+ public async execute(...args: [...T]) {
25
+ let prevIndex = -1;
26
+
27
+ const runner = async (index: number) => {
28
+ if (index === prevIndex) {
29
+ throw new Error('next() called multiple times');
30
+ }
31
+
32
+ prevIndex = index;
33
+
34
+ const middleware = Container.get(this.stack[index]);
35
+
36
+ await middleware.use(...args, () => {
37
+ return runner(index + 1);
38
+ });
39
+ }
40
+
41
+ await runner(0);
42
+ }
43
+
44
+ }
@@ -1,48 +1,48 @@
1
- import { Service } from 'typedi';
2
- import { Config } from '../config.service';
3
- import { match } from 'path-to-regexp';
4
- import { MockRule } from '../../types/yxorp-config';
5
-
6
-
7
- @Service({
8
- global: true
9
- })
10
- export class MockRulesMatcher {
11
- constructor(
12
- private config: Config
13
- ) {
14
- }
15
-
16
- public match(url: string, method: string): MockRule | undefined {
17
- const mockRules = this.config.get().mockRules || [];
18
-
19
- for (let mockRule of mockRules) {
20
- if (mockRule.disable) {
21
- continue;
22
- }
23
-
24
- if (mockRule.method.toLowerCase() !== method.toLowerCase()) {
25
- continue;
26
- }
27
-
28
- const matchResult = match<Record<string, string>>(mockRule.path, {
29
- decode: decodeURIComponent,
30
- })(url);
31
-
32
- if (matchResult) {
33
- return mockRule;
34
- }
35
- }
36
- }
37
-
38
- public params(url: string, mockRule: MockRule): Object | undefined {
39
- const matchResult = match(mockRule.path, {
40
- decode: decodeURIComponent,
41
- })(url);
42
-
43
- if (matchResult) {
44
- return matchResult.params;
45
- }
46
- }
47
-
48
- }
1
+ import { Service } from 'typedi';
2
+ import { Config } from '../config.service';
3
+ import { match } from 'path-to-regexp';
4
+ import { MockRule } from '../../types/yxorp-config';
5
+
6
+
7
+ @Service({
8
+ global: true
9
+ })
10
+ export class MockRulesMatcher {
11
+ constructor(
12
+ private config: Config
13
+ ) {
14
+ }
15
+
16
+ public match(url: string, method: string): MockRule | undefined {
17
+ const mockRules = this.config.get().mockRules || [];
18
+
19
+ for (let mockRule of mockRules) {
20
+ if (mockRule.disable) {
21
+ continue;
22
+ }
23
+
24
+ if (mockRule.method.toLowerCase() !== method.toLowerCase()) {
25
+ continue;
26
+ }
27
+
28
+ const matchResult = match<Record<string, string>>(mockRule.path, {
29
+ decode: decodeURIComponent,
30
+ })(url);
31
+
32
+ if (matchResult) {
33
+ return mockRule;
34
+ }
35
+ }
36
+ }
37
+
38
+ public params(url: string, mockRule: MockRule): Object | undefined {
39
+ const matchResult = match(mockRule.path, {
40
+ decode: decodeURIComponent,
41
+ })(url);
42
+
43
+ if (matchResult) {
44
+ return matchResult.params;
45
+ }
46
+ }
47
+
48
+ }