@depup/redbird 1.0.2-depup.0
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.
- package/LICENSE +24 -0
- package/README.md +35 -0
- package/changes.json +26 -0
- package/dist/docker.d.ts +30 -0
- package/dist/docker.js +136 -0
- package/dist/docker.js.map +1 -0
- package/dist/etcd-backend.d.ts +12 -0
- package/dist/etcd-backend.js +80 -0
- package/dist/etcd-backend.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/index.d.ts +2 -0
- package/dist/interfaces/index.js +3 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/proxy-options.d.ts +36 -0
- package/dist/interfaces/proxy-options.js +2 -0
- package/dist/interfaces/proxy-options.js.map +1 -0
- package/dist/interfaces/proxy-route.d.ts +14 -0
- package/dist/interfaces/proxy-route.js +2 -0
- package/dist/interfaces/proxy-route.js.map +1 -0
- package/dist/interfaces/proxy-target-url.d.ts +8 -0
- package/dist/interfaces/proxy-target-url.js +2 -0
- package/dist/interfaces/proxy-target-url.js.map +1 -0
- package/dist/interfaces/resolver.d.ts +12 -0
- package/dist/interfaces/resolver.js +2 -0
- package/dist/interfaces/resolver.js.map +1 -0
- package/dist/interfaces/route-options.d.ts +15 -0
- package/dist/interfaces/route-options.js +2 -0
- package/dist/interfaces/route-options.js.map +1 -0
- package/dist/letsencrypt.d.ts +19 -0
- package/dist/letsencrypt.js +127 -0
- package/dist/letsencrypt.js.map +1 -0
- package/dist/proxy.d.ts +122 -0
- package/dist/proxy.js +812 -0
- package/dist/proxy.js.map +1 -0
- package/dist/third-party/le-challenge-fs.d.ts +8 -0
- package/dist/third-party/le-challenge-fs.js +140 -0
- package/dist/third-party/le-challenge-fs.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +143 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Copyright (c) 2014, OptimalBits
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
8
|
+
list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
15
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
16
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
17
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
18
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
19
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
20
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
21
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
22
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
23
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
24
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @depup/redbird
|
|
2
|
+
|
|
3
|
+
> Dependency-bumped version of [redbird](https://www.npmjs.com/package/redbird)
|
|
4
|
+
|
|
5
|
+
Generated by [DepUp](https://github.com/depup/npm) -- all production
|
|
6
|
+
dependencies bumped to latest versions.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @depup/redbird
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Field | Value |
|
|
15
|
+
|-------|-------|
|
|
16
|
+
| Original | [redbird](https://www.npmjs.com/package/redbird) @ 1.0.2 |
|
|
17
|
+
| Processed | 2026-03-19 |
|
|
18
|
+
| Smoke test | passed |
|
|
19
|
+
| Deps updated | 5 |
|
|
20
|
+
|
|
21
|
+
## Dependency Changes
|
|
22
|
+
|
|
23
|
+
| Dependency | From | To |
|
|
24
|
+
|------------|------|-----|
|
|
25
|
+
| http-proxy | ^1.18.0 | ^1.18.1 |
|
|
26
|
+
| le-store-certbot | ^2.2.3 | ^2.2.4 |
|
|
27
|
+
| lodash | ^4.17.21 | ^4.17.23 |
|
|
28
|
+
| lru-cache | ^11.0.1 | ^11.2.7 |
|
|
29
|
+
| pino | ^9.4.0 | ^10.3.1 |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
Source: https://github.com/depup/npm | Original: https://www.npmjs.com/package/redbird
|
|
34
|
+
|
|
35
|
+
License inherited from the original package.
|
package/changes.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"bumped": {
|
|
3
|
+
"http-proxy": {
|
|
4
|
+
"from": "^1.18.0",
|
|
5
|
+
"to": "^1.18.1"
|
|
6
|
+
},
|
|
7
|
+
"le-store-certbot": {
|
|
8
|
+
"from": "^2.2.3",
|
|
9
|
+
"to": "^2.2.4"
|
|
10
|
+
},
|
|
11
|
+
"lodash": {
|
|
12
|
+
"from": "^4.17.21",
|
|
13
|
+
"to": "^4.17.23"
|
|
14
|
+
},
|
|
15
|
+
"lru-cache": {
|
|
16
|
+
"from": "^11.0.1",
|
|
17
|
+
"to": "^11.2.7"
|
|
18
|
+
},
|
|
19
|
+
"pino": {
|
|
20
|
+
"from": "^9.4.0",
|
|
21
|
+
"to": "^10.3.1"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"timestamp": "2026-03-19T03:02:07.934Z",
|
|
25
|
+
"totalUpdated": 5
|
|
26
|
+
}
|
package/dist/docker.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Redbird } from './proxy.js';
|
|
2
|
+
/**
|
|
3
|
+
Redbird Docker Module.
|
|
4
|
+
|
|
5
|
+
This module handles automatic regitration and de-registration of
|
|
6
|
+
services running on docker containers.
|
|
7
|
+
*/
|
|
8
|
+
export declare class DockerModule {
|
|
9
|
+
private redbird;
|
|
10
|
+
private targets;
|
|
11
|
+
private images;
|
|
12
|
+
private ports;
|
|
13
|
+
private dolphin;
|
|
14
|
+
private events;
|
|
15
|
+
private log;
|
|
16
|
+
constructor(redbird: Redbird, url: string);
|
|
17
|
+
registerIfNeeded(imageName: string, containerId: string, containerName: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Register route from a source to a given target.
|
|
20
|
+
* The target should be an image name. Starting several containers
|
|
21
|
+
* from the same image will automatically deliver the requests
|
|
22
|
+
* to each container in a round-robin fashion.
|
|
23
|
+
*
|
|
24
|
+
* @param src See {@link ReverseProxy.register}
|
|
25
|
+
* @param target Docker image (this string is evaluated as regexExp)
|
|
26
|
+
* @param opts Options like ssl and etc...
|
|
27
|
+
*/
|
|
28
|
+
register(src: string, target: string, opts: any): void;
|
|
29
|
+
registerContainer(src: string | URL, containerId: string, opts: any): Promise<void>;
|
|
30
|
+
}
|
package/dist/docker.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*eslint-env node */
|
|
2
|
+
'use strict';
|
|
3
|
+
/**
|
|
4
|
+
Redbird Docker Module.
|
|
5
|
+
|
|
6
|
+
This module handles automatic regitration and de-registration of
|
|
7
|
+
services running on docker containers.
|
|
8
|
+
*/
|
|
9
|
+
export class DockerModule {
|
|
10
|
+
constructor(redbird, url) {
|
|
11
|
+
this.redbird = redbird;
|
|
12
|
+
const Dolphin = require('dolphin');
|
|
13
|
+
this.redbird = redbird;
|
|
14
|
+
this.log = redbird.logger;
|
|
15
|
+
const targets = (this.targets = {});
|
|
16
|
+
this.ports = {};
|
|
17
|
+
// We keep an up-to-date table with all the images having
|
|
18
|
+
// containers running on the system.
|
|
19
|
+
const images = (this.images = {});
|
|
20
|
+
const dolphin = (this.dolphin = new Dolphin(url));
|
|
21
|
+
const _this = this;
|
|
22
|
+
// Start docker event listener
|
|
23
|
+
this.events = dolphin.events();
|
|
24
|
+
this.events.on('connected', () => {
|
|
25
|
+
// Fetch all running containers and register them if
|
|
26
|
+
// necessary.
|
|
27
|
+
dolphin.containers({ filters: { status: ['running'] } }).then((containers) => {
|
|
28
|
+
for (var i = 0; i < containers.length; i++) {
|
|
29
|
+
const container = containers[i];
|
|
30
|
+
this.registerIfNeeded(container.Image, container.Id, container.Names[0].replace('/', ''));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
this.events.on('event', (evt) => {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
let image;
|
|
37
|
+
let target;
|
|
38
|
+
(_a = this.log) === null || _a === void 0 ? void 0 : _a.info('Container %s changed to status %s', evt.Actor.Attributes.name, evt.status);
|
|
39
|
+
switch (evt.status) {
|
|
40
|
+
case 'start':
|
|
41
|
+
case 'restart':
|
|
42
|
+
case 'unpause':
|
|
43
|
+
this.registerIfNeeded(evt.from, evt.id, evt.Actor.Attributes.name);
|
|
44
|
+
break;
|
|
45
|
+
case 'stop':
|
|
46
|
+
case 'die':
|
|
47
|
+
case 'pause':
|
|
48
|
+
image = images[evt.from];
|
|
49
|
+
if (image) {
|
|
50
|
+
for (var targetName in targets) {
|
|
51
|
+
var match = isMatchingImageName(targetName, evt.from);
|
|
52
|
+
if (image[evt.id] === 'running' && match && _this.ports[evt.id]) {
|
|
53
|
+
target = targets[targetName];
|
|
54
|
+
(_b = this.log) === null || _b === void 0 ? void 0 : _b.info('Un-registering container %s for target %s', evt.Actor.Attributes.name, target.src);
|
|
55
|
+
_this.redbird.unregister(target.src, _this.ports[evt.id]);
|
|
56
|
+
}
|
|
57
|
+
image[evt.id] = 'stopped';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
// Nothing
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
this.events.on('error', (err) => {
|
|
66
|
+
this.log.error(err, 'dolphin docker event error');
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
registerIfNeeded(imageName, containerId, containerName) {
|
|
70
|
+
var _a;
|
|
71
|
+
const image = (this.images[imageName] = this.images[imageName] || {});
|
|
72
|
+
for (var targetName in this.targets) {
|
|
73
|
+
const match = isMatchingImageName(targetName, imageName);
|
|
74
|
+
if (match && image[containerId] !== 'running') {
|
|
75
|
+
const target = this.targets[targetName];
|
|
76
|
+
(_a = this.log) === null || _a === void 0 ? void 0 : _a.info('Registering container %s for target %s', containerName, target.src);
|
|
77
|
+
this.registerContainer(target.src, containerId, target.opts);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
image[containerId] = 'running';
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Register route from a source to a given target.
|
|
84
|
+
* The target should be an image name. Starting several containers
|
|
85
|
+
* from the same image will automatically deliver the requests
|
|
86
|
+
* to each container in a round-robin fashion.
|
|
87
|
+
*
|
|
88
|
+
* @param src See {@link ReverseProxy.register}
|
|
89
|
+
* @param target Docker image (this string is evaluated as regexExp)
|
|
90
|
+
* @param opts Options like ssl and etc...
|
|
91
|
+
*/
|
|
92
|
+
register(src, target, opts) {
|
|
93
|
+
var storedTarget = this.targets[target];
|
|
94
|
+
if (storedTarget && storedTarget.src == src) {
|
|
95
|
+
throw Error('Cannot register the same src and target twice');
|
|
96
|
+
}
|
|
97
|
+
this.targets[target] = {
|
|
98
|
+
src,
|
|
99
|
+
opts,
|
|
100
|
+
};
|
|
101
|
+
for (var imageName in this.images) {
|
|
102
|
+
const image = this.images[imageName];
|
|
103
|
+
for (var containerId in image) {
|
|
104
|
+
this.registerIfNeeded(imageName, containerId, containerId);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async registerContainer(src, containerId, opts) {
|
|
109
|
+
const targetPort = await containerPort(this.dolphin, containerId);
|
|
110
|
+
this.redbird.register(src, targetPort, opts);
|
|
111
|
+
this.ports[containerId] = targetPort;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function isMatchingImageName(targetName, imageName) {
|
|
115
|
+
var regex = new RegExp('^' + targetName + '$');
|
|
116
|
+
return regex.test(imageName);
|
|
117
|
+
}
|
|
118
|
+
function containerPort(dolphin, containerId) {
|
|
119
|
+
return dolphin.containers
|
|
120
|
+
.inspect(containerId)
|
|
121
|
+
.then((container) => {
|
|
122
|
+
const port = Object.keys(container.NetworkSettings.Ports)[0].split('/')[0];
|
|
123
|
+
const netNames = Object.keys(container.NetworkSettings.Networks);
|
|
124
|
+
if (netNames.length === 1) {
|
|
125
|
+
const ip = container.NetworkSettings.Networks[netNames[0]].IPAddress;
|
|
126
|
+
if (port && ip) {
|
|
127
|
+
return 'http://' + ip + ':' + port;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
//TODO: Implements opts for manually choosing the network/ip/port...
|
|
132
|
+
}
|
|
133
|
+
throw Error('No valid address or port ' + container.IPAddress + ':' + port);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../lib/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Redbird ETCD Module
|
|
3
|
+
This module handles automatic proxy registration via etcd
|
|
4
|
+
*/
|
|
5
|
+
import { Redbird } from './proxy.js';
|
|
6
|
+
export declare class ETCDModule {
|
|
7
|
+
private redbird;
|
|
8
|
+
private etcd;
|
|
9
|
+
private etcd_dir;
|
|
10
|
+
private watcher;
|
|
11
|
+
constructor(redbird: Redbird, options: any);
|
|
12
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/*eslint-env node */
|
|
2
|
+
'use strict';
|
|
3
|
+
export class ETCDModule {
|
|
4
|
+
constructor(redbird, options) {
|
|
5
|
+
this.redbird = redbird;
|
|
6
|
+
const Etcd = require('node-etcd');
|
|
7
|
+
// Create Redbird Instance and Log
|
|
8
|
+
this.redbird = redbird;
|
|
9
|
+
const log = redbird.logger;
|
|
10
|
+
const _this = this;
|
|
11
|
+
// Create node-etcd Instance
|
|
12
|
+
this.etcd = new Etcd(options.hosts, options.ssloptions);
|
|
13
|
+
this.etcd_dir = typeof options.path !== 'undefined' ? options.path : 'redbird';
|
|
14
|
+
// Create directory if not created
|
|
15
|
+
this.etcd.get(this.etcd_dir, function (err, body, header) {
|
|
16
|
+
if (err && err.errorCode == 100) {
|
|
17
|
+
_this.etcd.mkdir(_this.etcd_dir, function (err) {
|
|
18
|
+
if (err) {
|
|
19
|
+
log.error(err, 'etcd backend error');
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
createWatcher();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else if (!err && body.node.dir) {
|
|
27
|
+
createWatcher();
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
log.error(err, 'etcd backend error');
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
// Helper function to check if values contain settings
|
|
34
|
+
function IsJsonString(str) {
|
|
35
|
+
try {
|
|
36
|
+
JSON.parse(str);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// Helper function to pretify etcd directory strings
|
|
44
|
+
function removeEtcDir(str) {
|
|
45
|
+
return str.replace(_this.etcd_dir, '').replace(/^\/+|\/+$/g, '');
|
|
46
|
+
}
|
|
47
|
+
function createWatcher() {
|
|
48
|
+
// Watch etcd directory
|
|
49
|
+
_this.watcher = _this.etcd.watcher(_this.etcd_dir, null, { recursive: true });
|
|
50
|
+
// On Add/Update
|
|
51
|
+
_this.watcher.on('change', function (body, headers) {
|
|
52
|
+
if (body.node.key && body.node.value && !IsJsonString(body.node.value)) {
|
|
53
|
+
_this.redbird.register(removeEtcDir(body.node.key), body.node.value);
|
|
54
|
+
}
|
|
55
|
+
else if (body.node.key && body.node.value && IsJsonString(body.node.value)) {
|
|
56
|
+
var config = JSON.parse(body.node.value);
|
|
57
|
+
if (typeof config.docker !== 'undefined') {
|
|
58
|
+
require('./index.js')
|
|
59
|
+
.docker(_this.redbird)
|
|
60
|
+
.register(body.node.key, body.node.value.docker, body.node.value);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
_this.redbird.register(removeEtcDir(body.node.key), config.hosts, config);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// On Delete
|
|
68
|
+
_this.watcher.on('delete', function (body, headers) {
|
|
69
|
+
if (body.node.key) {
|
|
70
|
+
_this.redbird.unregister(removeEtcDir(body.node.key));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// Handle Errors
|
|
74
|
+
_this.watcher.on('error', function (err) {
|
|
75
|
+
log.error(err, 'etcd backend error');
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=etcd-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etcd-backend.js","sourceRoot":"","sources":["../lib/etcd-backend.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,YAAY,CAAC;AACb,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import http, { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import httpProxy, { ProxyTargetUrl } from 'http-proxy';
|
|
3
|
+
import { Socket } from 'net';
|
|
4
|
+
import pino from 'pino';
|
|
5
|
+
import { Resolver } from './resolver.js';
|
|
6
|
+
export interface SSLConfig {
|
|
7
|
+
port?: number;
|
|
8
|
+
ip?: string;
|
|
9
|
+
key?: string;
|
|
10
|
+
cert?: string;
|
|
11
|
+
ca?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ProxyOptions {
|
|
14
|
+
port?: number;
|
|
15
|
+
host?: string;
|
|
16
|
+
keepAlive?: boolean;
|
|
17
|
+
preferForwardedHost?: boolean;
|
|
18
|
+
httpProxy?: httpProxy.ServerOptions;
|
|
19
|
+
logger?: pino.Logger;
|
|
20
|
+
cluster?: number;
|
|
21
|
+
letsencrypt?: {
|
|
22
|
+
path: string;
|
|
23
|
+
port: number;
|
|
24
|
+
renewWithin?: number;
|
|
25
|
+
minRenewTime?: number;
|
|
26
|
+
};
|
|
27
|
+
resolvers?: Resolver[];
|
|
28
|
+
ntlm?: boolean;
|
|
29
|
+
xfwd?: boolean;
|
|
30
|
+
secure?: boolean;
|
|
31
|
+
timeout?: number;
|
|
32
|
+
proxyTimeout?: number;
|
|
33
|
+
ssl?: SSLConfig | SSLConfig[];
|
|
34
|
+
errorHandler?: (err: NodeJS.ErrnoException, req: IncomingMessage, res: ServerResponse | Socket, target?: ProxyTargetUrl) => void;
|
|
35
|
+
serverModule?: typeof http;
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-options.js","sourceRoot":"","sources":["../../lib/interfaces/proxy-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ProxyTargetUrl } from './proxy-target-url.js';
|
|
2
|
+
import { RouteOptions } from './route-options.js';
|
|
3
|
+
/**
|
|
4
|
+
* ProxyRoute interface
|
|
5
|
+
* @description
|
|
6
|
+
* Interface for ProxyRoute
|
|
7
|
+
*/
|
|
8
|
+
export interface ProxyRoute {
|
|
9
|
+
urls?: ProxyTargetUrl[];
|
|
10
|
+
path?: string;
|
|
11
|
+
rr?: number;
|
|
12
|
+
isResolved?: boolean;
|
|
13
|
+
opts?: RouteOptions;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-route.js","sourceRoot":"","sources":["../../lib/interfaces/proxy-route.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-target-url.js","sourceRoot":"","sources":["../../lib/interfaces/proxy-target-url.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IncomingMessage } from 'http';
|
|
2
|
+
import { RouteOptions } from './route-options.js';
|
|
3
|
+
export type ResolverFnResult = string | {
|
|
4
|
+
path?: string;
|
|
5
|
+
url: string;
|
|
6
|
+
opts?: RouteOptions;
|
|
7
|
+
} | null | undefined;
|
|
8
|
+
export type ResolverFn = (host: string, url: string, req?: IncomingMessage) => ResolverFnResult | Promise<ResolverFnResult>;
|
|
9
|
+
export interface Resolver {
|
|
10
|
+
fn: ResolverFn;
|
|
11
|
+
priority: number;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../lib/interfaces/resolver.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ProxyTargetUrl } from './proxy-target-url.js';
|
|
2
|
+
export interface RouteOptions {
|
|
3
|
+
useTargetHostHeader?: boolean;
|
|
4
|
+
ssl?: {
|
|
5
|
+
key?: string;
|
|
6
|
+
cert?: string;
|
|
7
|
+
ca?: string;
|
|
8
|
+
letsencrypt?: {
|
|
9
|
+
email: string;
|
|
10
|
+
production: boolean;
|
|
11
|
+
lazy?: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
onRequest?: (req: any, res: any, target: ProxyTargetUrl) => void;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-options.js","sourceRoot":"","sources":["../../lib/interfaces/route-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Letsecript module for Redbird (c) Optimalbits 2016-2024
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
8
|
+
import pino from 'pino';
|
|
9
|
+
declare function init(certPath: string, port: number, logger: pino.Logger<never, boolean>): import("http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
10
|
+
/**
|
|
11
|
+
* Gets the certificates for the given domain.
|
|
12
|
+
* Handles all the LetsEncrypt protocol. Uses
|
|
13
|
+
* existing certificates if any, or negotiates a new one.
|
|
14
|
+
* Returns a promise that resolves to an object with the certificates.
|
|
15
|
+
* TODO: We should use something like https://github.com/PaquitoSoft/memored/blob/master/index.js
|
|
16
|
+
* to avoid
|
|
17
|
+
*/
|
|
18
|
+
declare function getCertificates(domain: string, email: string, loopbackPort: number, production: boolean, renew: boolean, logger: pino.Logger<never, boolean>): Promise<any>;
|
|
19
|
+
export { init, getCertificates };
|