@onlyne/mcp-gateway 3.1.0 → 3.2.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/README.md +25 -1
- package/dist/config.d.ts +69 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +210 -0
- package/dist/config.js.map +1 -0
- package/dist/cron.d.ts +23 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +112 -0
- package/dist/cron.js.map +1 -0
- package/dist/exec.d.ts +33 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +155 -0
- package/dist/exec.js.map +1 -0
- package/dist/gateway-text.d.ts +26 -0
- package/dist/gateway-text.d.ts.map +1 -0
- package/dist/gateway-text.js +47 -0
- package/dist/gateway-text.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +274 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/{src/main.ts → dist/main.js} +20 -32
- package/dist/main.js.map +1 -0
- package/dist/mounts.d.ts +151 -0
- package/dist/mounts.d.ts.map +1 -0
- package/dist/mounts.js +927 -0
- package/dist/mounts.js.map +1 -0
- package/package.json +17 -12
- package/src/config.ts +0 -182
- package/src/cron.ts +0 -122
- package/src/exec.ts +0 -163
- package/src/gateway-text.ts +0 -51
- package/src/index.ts +0 -214
- package/src/mounts.ts +0 -1043
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ bunx onlyne-mcp-gateway ./gateway.json
|
|
|
23
23
|
{
|
|
24
24
|
"name": "hindsight",
|
|
25
25
|
"url": "http://localhost:8888/mcp/example-bank/",
|
|
26
|
+
"allowed_tools": ["recall", "retain"],
|
|
26
27
|
"timeout_ms": 60000,
|
|
27
28
|
"controllers": ["urn:onlyne:agent:main"]
|
|
28
29
|
}
|
|
@@ -30,7 +31,25 @@ bunx onlyne-mcp-gateway ./gateway.json
|
|
|
30
31
|
}
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
`headers` adds per-request headers such as an API key and is never logged. `
|
|
34
|
+
`headers` adds per-request headers such as an API key and is never logged. `allowed_tools` limits
|
|
35
|
+
which listed tools may be called; omit it for every listed tool, pass `[]` to deny all. A denied
|
|
36
|
+
tool fails with `forbidden` before any connection or request. A local server uses stdio instead
|
|
37
|
+
of a URL:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"name": "filesystem",
|
|
42
|
+
"transport": "stdio",
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
|
|
45
|
+
"cwd": "/tmp",
|
|
46
|
+
"allowed_tools": ["read_file", "list_directory"],
|
|
47
|
+
"controllers": ["urn:onlyne:agent:main"]
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`command`, `args`, `env` and `cwd` are passed to the child process as separate values; no shell
|
|
52
|
+
string is built. `controllers` lists
|
|
34
53
|
the nodes allowed to call a server's tools; an empty list leaves the node owner alone.
|
|
35
54
|
`language` accepts `en` or `zh-CN` and otherwise follows `ONLYNE_LANG`, `LC_ALL`, or `LANG`.
|
|
36
55
|
|
|
@@ -121,6 +140,11 @@ import { createMcpGateway } from '@onlyne/mcp-gateway';
|
|
|
121
140
|
|
|
122
141
|
The result carries the node, the connections, and a `fetch` handler.
|
|
123
142
|
|
|
143
|
+
`McpGateway.bridge` exposes the read-only MCP resource primitives for hosts: `listResources`,
|
|
144
|
+
`readResource`, `subscribe`, `unsubscribe`, `syncSubscriptions` and `close`. Reads return server
|
|
145
|
+
data only; they never admit a message or write business state. The bridge reports subscription
|
|
146
|
+
loss through its observation callbacks and withdraws every subscription on close.
|
|
147
|
+
|
|
124
148
|
## License
|
|
125
149
|
|
|
126
150
|
MIT.
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type NodeId } from '@onlyne/lib';
|
|
2
|
+
import type { Locale } from '@onlyne/node-host/i18n';
|
|
3
|
+
/** Settings every configured MCP server shares. */
|
|
4
|
+
interface ServerConfigBase {
|
|
5
|
+
name: string;
|
|
6
|
+
timeout_ms?: number;
|
|
7
|
+
/** Who may call this server's tools. Empty means the node owner only. */
|
|
8
|
+
controllers?: NodeId[];
|
|
9
|
+
/**
|
|
10
|
+
* The local tool policy (RFC 0015 §4). Absent allows every tool the server lists; an empty
|
|
11
|
+
* list allows none. It is checked before a request leaves the gateway.
|
|
12
|
+
*/
|
|
13
|
+
allowed_tools?: string[];
|
|
14
|
+
}
|
|
15
|
+
/** An HTTP streamable MCP server; the transport is implicit when only `url` is given. */
|
|
16
|
+
export interface HttpServerConfig extends ServerConfigBase {
|
|
17
|
+
transport?: 'http';
|
|
18
|
+
url: string;
|
|
19
|
+
/** Extra request headers (an API key, a bank header); never logged. */
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
/** A locally spawned MCP server; `command` and `args` are spawned directly, never through a shell. */
|
|
23
|
+
export interface StdioServerConfig extends ServerConfigBase {
|
|
24
|
+
transport: 'stdio';
|
|
25
|
+
command: string;
|
|
26
|
+
args?: string[];
|
|
27
|
+
env?: Record<string, string>;
|
|
28
|
+
cwd?: string;
|
|
29
|
+
}
|
|
30
|
+
/** One configured MCP server: exactly one of the HTTP and stdio transport contracts. */
|
|
31
|
+
export type ServerConfig = HttpServerConfig | StdioServerConfig;
|
|
32
|
+
/** One locally allowlisted executable a scheduled mount may run: the mount names this id only. */
|
|
33
|
+
export interface MountCommandConfig {
|
|
34
|
+
id: string;
|
|
35
|
+
command: string;
|
|
36
|
+
args?: string[];
|
|
37
|
+
cwd?: string;
|
|
38
|
+
}
|
|
39
|
+
/** One MCP tool a scheduled mount may call; the server's own controller list still applies. */
|
|
40
|
+
export interface MountToolConfig {
|
|
41
|
+
server: string;
|
|
42
|
+
tool: string;
|
|
43
|
+
}
|
|
44
|
+
export interface MountsConfig {
|
|
45
|
+
/** The nodes that may mount, inspect and cancel tasks on their own scheduler resource. */
|
|
46
|
+
controllers: NodeId[];
|
|
47
|
+
commands: MountCommandConfig[];
|
|
48
|
+
tools: MountToolConfig[];
|
|
49
|
+
tick_ms: number;
|
|
50
|
+
}
|
|
51
|
+
export interface GatewayConfig {
|
|
52
|
+
node: {
|
|
53
|
+
id: NodeId;
|
|
54
|
+
};
|
|
55
|
+
server: {
|
|
56
|
+
bind: string;
|
|
57
|
+
port: number;
|
|
58
|
+
};
|
|
59
|
+
storage_path: string;
|
|
60
|
+
servers: ServerConfig[];
|
|
61
|
+
/** Scheduled mounts; absent means the gateway serves no scheduler resource at all. */
|
|
62
|
+
mounts?: MountsConfig;
|
|
63
|
+
/** The language of the gateway's own console text; unset follows `ONLYNE_LANG`. */
|
|
64
|
+
language?: Locale;
|
|
65
|
+
}
|
|
66
|
+
/** Loads the gateway configuration from one JSON file; environment retuning comes later. */
|
|
67
|
+
export declare function loadConfig(path: string): Promise<GatewayConfig>;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAIrD,mDAAmD;AACnD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,yFAAyF;AACzF,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,sGAAsG;AACtG,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEhE,kGAAkG;AAClG,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,+FAA+F;AAC/F,MAAM,WAAW,eAAe;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAEjE,MAAM,WAAW,YAAY;IAC3B,0FAA0F;IAC1F,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACrB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,sFAAsF;IACtF,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoKD,4FAA4F;AAC5F,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAsCrE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { OnlyneError } from '@onlyne/lib';
|
|
2
|
+
import { t } from './gateway-text.js';
|
|
3
|
+
import { MOUNTS_RESOURCE_PREFIX } from './mounts.js';
|
|
4
|
+
const requireObject = (value, field) => {
|
|
5
|
+
if (value === undefined || value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
6
|
+
throw new OnlyneError('invalid_request', t('config.object', { field }));
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
};
|
|
10
|
+
const requireString = (container, field) => {
|
|
11
|
+
const value = container[field];
|
|
12
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
13
|
+
throw new OnlyneError('invalid_request', t('config.string', { field }));
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
};
|
|
17
|
+
const requireStrings = (value, field) => {
|
|
18
|
+
if (value === undefined)
|
|
19
|
+
return [];
|
|
20
|
+
if (!Array.isArray(value) || value.some(item => typeof item !== 'string' || item.length === 0)) {
|
|
21
|
+
throw new OnlyneError('invalid_request', t('config.stringList', { field }));
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
function parseMounts(raw, owner, servers) {
|
|
26
|
+
if (raw === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
const record = requireObject(raw, 'mounts');
|
|
29
|
+
const controllers = [...new Set(requireStrings(record.controllers, 'mounts.controllers'))];
|
|
30
|
+
if (controllers.length === 0) {
|
|
31
|
+
throw new OnlyneError('invalid_request', t('config.mountsControllers'));
|
|
32
|
+
}
|
|
33
|
+
if (controllers.includes(owner)) {
|
|
34
|
+
throw new OnlyneError('invalid_request', t('config.mountsOwner', { owner }));
|
|
35
|
+
}
|
|
36
|
+
const commands = (record.commands === undefined ? [] : record.commands);
|
|
37
|
+
if (!Array.isArray(commands))
|
|
38
|
+
throw new OnlyneError('invalid_request', t('config.mountsCommands'));
|
|
39
|
+
const commandIds = new Set();
|
|
40
|
+
const parsedCommands = commands.map((entry, index) => {
|
|
41
|
+
const item = requireObject(entry, `mounts.commands[${index}]`);
|
|
42
|
+
const id = requireString(item, 'id');
|
|
43
|
+
if (commandIds.has(id))
|
|
44
|
+
throw new OnlyneError('invalid_request', t('config.mountsDuplicate', { kind: 'command', id }));
|
|
45
|
+
commandIds.add(id);
|
|
46
|
+
const args = item.args === undefined ? [] : requireStrings(item.args, `mounts.commands[${index}].args`);
|
|
47
|
+
const cwd = item.cwd === undefined ? undefined : requireString(item, 'cwd');
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
command: requireString(item, 'command'),
|
|
51
|
+
...(args.length === 0 ? {} : { args }),
|
|
52
|
+
...(cwd === undefined ? {} : { cwd }),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
const tools = (record.tools === undefined ? [] : record.tools);
|
|
56
|
+
if (!Array.isArray(tools))
|
|
57
|
+
throw new OnlyneError('invalid_request', t('config.mountsTools'));
|
|
58
|
+
const toolIds = new Set();
|
|
59
|
+
const parsedTools = tools.map((entry, index) => {
|
|
60
|
+
const item = requireObject(entry, `mounts.tools[${index}]`);
|
|
61
|
+
const server = requireString(item, 'server');
|
|
62
|
+
const tool = requireString(item, 'tool');
|
|
63
|
+
const configured = servers.get(server);
|
|
64
|
+
if (configured === undefined) {
|
|
65
|
+
throw new OnlyneError('invalid_request', t('config.mountsToolServer', { server }));
|
|
66
|
+
}
|
|
67
|
+
// A scheduled call runs with the same local policy as a direct resource operation; refusing
|
|
68
|
+
// a tool the policy already denies at load time keeps the scheduler from starting a task
|
|
69
|
+
// that can only fail.
|
|
70
|
+
if (configured.allowed_tools !== undefined && !configured.allowed_tools.includes(tool)) {
|
|
71
|
+
throw new OnlyneError('invalid_request', `mounts.tools names ${server}/${tool}, which the server's allowed_tools policy denies.`);
|
|
72
|
+
}
|
|
73
|
+
const pair = `${server}\u0000${tool}`;
|
|
74
|
+
if (toolIds.has(pair))
|
|
75
|
+
throw new OnlyneError('invalid_request', t('config.mountsDuplicate', { kind: 'tool', id: `${server}/${tool}` }));
|
|
76
|
+
toolIds.add(pair);
|
|
77
|
+
return { server, tool };
|
|
78
|
+
});
|
|
79
|
+
const tick = record.tick_ms === undefined ? 1_000 : record.tick_ms;
|
|
80
|
+
if (typeof tick !== 'number' || !Number.isInteger(tick) || tick < 100 || tick > 60_000) {
|
|
81
|
+
throw new OnlyneError('invalid_request', t('config.mountTick'));
|
|
82
|
+
}
|
|
83
|
+
return { controllers, commands: parsedCommands, tools: parsedTools, tick_ms: tick };
|
|
84
|
+
}
|
|
85
|
+
/** `language` is exactly `en` or `zh-CN`: a near miss would silently pick a different console language. */
|
|
86
|
+
const parseLanguage = (value) => {
|
|
87
|
+
if (value === undefined)
|
|
88
|
+
return undefined;
|
|
89
|
+
if (value === 'en' || value === 'zh-CN')
|
|
90
|
+
return value;
|
|
91
|
+
throw new OnlyneError('invalid_request', t('config.language', { value: JSON.stringify(value) }));
|
|
92
|
+
};
|
|
93
|
+
/** Environment entries are opaque strings; an empty value is legal, a non-string is not. */
|
|
94
|
+
function parseEnvironment(value, field) {
|
|
95
|
+
if (value === undefined)
|
|
96
|
+
return undefined;
|
|
97
|
+
const record = requireObject(value, field);
|
|
98
|
+
const environment = {};
|
|
99
|
+
for (const [key, entry] of Object.entries(record)) {
|
|
100
|
+
if (typeof entry !== 'string') {
|
|
101
|
+
throw new OnlyneError('invalid_request', t('config.string', { field: `${field}.${key}` }));
|
|
102
|
+
}
|
|
103
|
+
environment[key] = entry;
|
|
104
|
+
}
|
|
105
|
+
return Object.keys(environment).length === 0 ? undefined : environment;
|
|
106
|
+
}
|
|
107
|
+
/** One `servers[]` entry: the transport decides which fields are required and which are refused. */
|
|
108
|
+
function parseServer(item, index) {
|
|
109
|
+
const field = `servers[${index}]`;
|
|
110
|
+
const timeout = item.timeout_ms;
|
|
111
|
+
const rawAllowed = item.allowed_tools;
|
|
112
|
+
const allowed = rawAllowed === undefined
|
|
113
|
+
? undefined
|
|
114
|
+
: [...new Set(requireStrings(rawAllowed, `${field}.allowed_tools`))];
|
|
115
|
+
const controllers = item.controllers;
|
|
116
|
+
const shared = {
|
|
117
|
+
name: requireString(item, 'name'),
|
|
118
|
+
...(typeof timeout === 'number' ? { timeout_ms: timeout } : {}),
|
|
119
|
+
...(allowed === undefined ? {} : { allowed_tools: allowed }),
|
|
120
|
+
...(Array.isArray(controllers)
|
|
121
|
+
? { controllers: controllers.filter((value) => typeof value === 'string' && value.length > 0) }
|
|
122
|
+
: {}),
|
|
123
|
+
};
|
|
124
|
+
const declared = item.transport;
|
|
125
|
+
if (declared !== undefined && declared !== 'http' && declared !== 'stdio') {
|
|
126
|
+
throw new OnlyneError('invalid_request', `${field}.transport is 'http' or 'stdio'.`);
|
|
127
|
+
}
|
|
128
|
+
// An existing configuration names only `url`; that stays the HTTP transport without a rewrite.
|
|
129
|
+
const transport = declared ?? (item.url !== undefined ? 'http' : undefined);
|
|
130
|
+
if (transport === 'http') {
|
|
131
|
+
for (const key of ['command', 'args', 'env', 'cwd']) {
|
|
132
|
+
if (item[key] !== undefined) {
|
|
133
|
+
throw new OnlyneError('invalid_request', `${field} uses the http transport, so it cannot set ${key}.`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const rawHeaders = item.headers === undefined ? undefined : requireObject(item.headers, `${field}.headers`);
|
|
137
|
+
const headers = rawHeaders === undefined
|
|
138
|
+
? undefined
|
|
139
|
+
: Object.fromEntries(Object.entries(rawHeaders).filter((pair) => typeof pair[1] === 'string'));
|
|
140
|
+
return {
|
|
141
|
+
...shared,
|
|
142
|
+
transport: 'http',
|
|
143
|
+
url: requireString(item, 'url'),
|
|
144
|
+
...(headers === undefined || Object.keys(headers).length === 0 ? {} : { headers }),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (transport === 'stdio') {
|
|
148
|
+
if (item.url !== undefined) {
|
|
149
|
+
throw new OnlyneError('invalid_request', `${field} uses the stdio transport, so it cannot set url.`);
|
|
150
|
+
}
|
|
151
|
+
if (item.headers !== undefined) {
|
|
152
|
+
throw new OnlyneError('invalid_request', `${field} uses the stdio transport, so it cannot set headers.`);
|
|
153
|
+
}
|
|
154
|
+
const args = item.args === undefined ? [] : requireStrings(item.args, `${field}.args`);
|
|
155
|
+
const env = parseEnvironment(item.env, `${field}.env`);
|
|
156
|
+
const cwd = item.cwd === undefined ? undefined : requireString(item, 'cwd');
|
|
157
|
+
return {
|
|
158
|
+
...shared,
|
|
159
|
+
transport: 'stdio',
|
|
160
|
+
command: requireString(item, 'command'),
|
|
161
|
+
...(args.length === 0 ? {} : { args }),
|
|
162
|
+
...(env === undefined ? {} : { env }),
|
|
163
|
+
...(cwd === undefined ? {} : { cwd }),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
throw new OnlyneError('invalid_request', `${field} needs transport 'http' with url, or transport 'stdio' with command.`);
|
|
167
|
+
}
|
|
168
|
+
/** Loads the gateway configuration from one JSON file; environment retuning comes later. */
|
|
169
|
+
export async function loadConfig(path) {
|
|
170
|
+
let file;
|
|
171
|
+
try {
|
|
172
|
+
file = JSON.parse(await Bun.file(path).text());
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
throw new OnlyneError('invalid_request', t('config.unreadable', { path }));
|
|
176
|
+
}
|
|
177
|
+
const raw = requireObject(file, 'the configuration root');
|
|
178
|
+
const node = requireObject(raw.node, 'node');
|
|
179
|
+
const server = requireObject(raw.server, 'server');
|
|
180
|
+
const storage = requireObject(raw.storage, 'storage');
|
|
181
|
+
const language = parseLanguage(raw.language);
|
|
182
|
+
const owner = requireString(node, 'id');
|
|
183
|
+
const rawServers = raw.servers === undefined ? [] : raw.servers;
|
|
184
|
+
if (!Array.isArray(rawServers)) {
|
|
185
|
+
throw new OnlyneError('invalid_request', t('config.servers'));
|
|
186
|
+
}
|
|
187
|
+
const servers = rawServers.map((entry, index) => parseServer(requireObject(entry, `servers[${index}]`), index));
|
|
188
|
+
const names = new Set();
|
|
189
|
+
for (const entry of servers) {
|
|
190
|
+
if (names.has(entry.name))
|
|
191
|
+
throw new OnlyneError('invalid_request', t('config.duplicateName', { name: entry.name }));
|
|
192
|
+
if (entry.name.startsWith(MOUNTS_RESOURCE_PREFIX)) {
|
|
193
|
+
throw new OnlyneError('invalid_request', t('config.reservedName', { name: entry.name, prefix: MOUNTS_RESOURCE_PREFIX }));
|
|
194
|
+
}
|
|
195
|
+
names.add(entry.name);
|
|
196
|
+
}
|
|
197
|
+
const mounts = parseMounts(raw.mounts, owner, new Map(servers.map(entry => [entry.name, entry])));
|
|
198
|
+
return {
|
|
199
|
+
node: { id: owner },
|
|
200
|
+
server: {
|
|
201
|
+
bind: typeof server.bind === 'string' && server.bind.length > 0 ? server.bind : '127.0.0.1',
|
|
202
|
+
port: typeof server.port === 'number' ? server.port : 0,
|
|
203
|
+
},
|
|
204
|
+
storage_path: requireString(storage, 'path'),
|
|
205
|
+
servers,
|
|
206
|
+
...(mounts === undefined ? {} : { mounts }),
|
|
207
|
+
...(language === undefined ? {} : { language }),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA0B,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAiErD,MAAM,aAAa,GAAG,CAAC,KAAuB,EAAE,KAAa,EAAwB,EAAE;IACrF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,KAA6B,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,SAAkC,EAAE,KAAa,EAAU,EAAE;IAClF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,KAAuB,EAAE,KAAa,EAAY,EAAE;IAC1E,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAiB,CAAC;AAC3B,CAAC,CAAC;AAEF,SAAS,WAAW,CAAC,GAAqB,EAAE,KAAa,EAAE,OAA0C;IACnG,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC3F,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACnG,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAsB,EAAE;QACvE,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,EAAE,mBAAmB,KAAK,GAAG,CAAC,CAAC;QAC/D,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACvH,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,KAAK,QAAQ,CAAC,CAAC;QACxG,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5E,OAAO;YACL,EAAE;YACF,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YACtC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;SACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC7F,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAmB,EAAE;QAC9D,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,EAAE,gBAAgB,KAAK,GAAG,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACrF,CAAC;QACD,4FAA4F;QAC5F,yFAAyF;QACzF,sBAAsB;QACtB,IAAI,UAAU,CAAC,aAAa,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACvF,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,sBAAsB,MAAM,IAAI,IAAI,mDAAmD,CAAC,CAAC;QACpI,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,MAAM,SAAS,IAAI,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACxI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACnE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;QACvF,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACtF,CAAC;AAED,2GAA2G;AAC3G,MAAM,aAAa,GAAG,CAAC,KAAuB,EAAsB,EAAE;IACpE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,4FAA4F;AAC5F,SAAS,gBAAgB,CAAC,KAAuB,EAAE,KAAa;IAC9D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3C,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7F,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;AACzE,CAAC;AAED,oGAAoG;AACpG,SAAS,WAAW,CAAC,IAA0B,EAAE,KAAa;IAC5D,MAAM,KAAK,GAAG,WAAW,KAAK,GAAG,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;IAChC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC;IACtC,MAAM,OAAO,GAAG,UAAU,KAAK,SAAS;QACtC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACrC,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC;QACjC,GAAG,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;QAC5D,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAC5B,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;YAChH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;IAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1E,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,GAAG,KAAK,kCAAkC,CAAC,CAAC;IACvF,CAAC;IACD,+FAA+F;IAC/F,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5E,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAU,EAAE,CAAC;YAC7D,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,GAAG,KAAK,8CAA8C,GAAG,GAAG,CAAC,CAAC;YACzG,CAAC;QACH,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,UAAU,CAAC,CAAC;QAC5G,MAAM,OAAO,GAAG,UAAU,KAAK,SAAS;YACtC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAA4B,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;QAC3H,OAAO;YACL,GAAG,MAAM;YACT,SAAS,EAAE,MAAM;YACjB,GAAG,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC;YAC/B,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;SACnF,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,GAAG,KAAK,kDAAkD,CAAC,CAAC;QACvG,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,GAAG,KAAK,sDAAsD,CAAC,CAAC;QAC3G,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;QACvF,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5E,OAAO;YACL,GAAG,MAAM;YACT,SAAS,EAAE,OAAO;YAClB,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YACtC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;YACrC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;SACtC,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,GAAG,KAAK,sEAAsE,CAAC,CAAC;AAC3H,CAAC;AAED,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,IAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAS,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAW,CAAC;IAClD,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IAChE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,KAAK,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAChH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACrH,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC;QAC3H,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClG,OAAO;QACL,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE;QACnB,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW;YAC3F,IAAI,EAAE,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACxD;QACD,YAAY,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC;QAC5C,OAAO;QACP,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3C,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC"}
|
package/dist/cron.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A parsed five-field cron expression. Every field becomes a sorted list of the values it
|
|
3
|
+
* admits, so matching is a membership test and never a re-parse. Time is UTC: a mounted task
|
|
4
|
+
* must fire at the same instant after a restart, in every process, on every host.
|
|
5
|
+
*/
|
|
6
|
+
export interface CronSchedule {
|
|
7
|
+
readonly minutes: readonly number[];
|
|
8
|
+
readonly hours: readonly number[];
|
|
9
|
+
readonly days: readonly number[];
|
|
10
|
+
readonly months: readonly number[];
|
|
11
|
+
readonly weekdays: readonly number[];
|
|
12
|
+
/** Which of the day fields the expression restricts; both restricted match either (Vixie). */
|
|
13
|
+
readonly domRestricted: boolean;
|
|
14
|
+
readonly dowRestricted: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Parses one five-field expression; throwing `invalid_request` names the offending field. */
|
|
17
|
+
export declare function parseCron(expression: string): CronSchedule;
|
|
18
|
+
/**
|
|
19
|
+
* The first instant strictly after `fromMs` that the expression admits, to the minute, in UTC.
|
|
20
|
+
* `undefined` means no occurrence inside the five-year horizon (for example `0 0 31 2 *`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function nextCronTime(schedule: CronSchedule, fromMs: number): number | undefined;
|
|
23
|
+
//# sourceMappingURL=cron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,8FAA8F;IAC9F,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAwDD,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAY1D;AAQD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAwBvF"}
|
package/dist/cron.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { OnlyneError } from '@onlyne/lib';
|
|
2
|
+
const FIELDS = [
|
|
3
|
+
{ name: 'minute', min: 0, max: 59 },
|
|
4
|
+
{ name: 'hour', min: 0, max: 23 },
|
|
5
|
+
{ name: 'day-of-month', min: 1, max: 31 },
|
|
6
|
+
{ name: 'month', min: 1, max: 12 },
|
|
7
|
+
// 7 is Sunday: accepted as an input alias only, and normalized before the schedule is stored.
|
|
8
|
+
{ name: 'day-of-week', min: 0, max: 7 },
|
|
9
|
+
];
|
|
10
|
+
/** `7` is Sunday in the day-of-week field; the schedule normalizes it to `0`. */
|
|
11
|
+
const WEEKDAY_ALIAS = { '7': 0 };
|
|
12
|
+
const RANGE = /^(\d+)-(\d+)$/;
|
|
13
|
+
const NUMBER = /^\d+$/;
|
|
14
|
+
function parseField(text, spec) {
|
|
15
|
+
if (text.length === 0)
|
|
16
|
+
throw cronError(`The ${spec.name} field is empty.`);
|
|
17
|
+
const values = new Set();
|
|
18
|
+
for (const part of text.split(',')) {
|
|
19
|
+
if (part.length === 0)
|
|
20
|
+
throw cronError(`The ${spec.name} field holds an empty list item.`);
|
|
21
|
+
const [rangeText = '', stepText, extra] = part.split('/');
|
|
22
|
+
if (extra !== undefined)
|
|
23
|
+
throw cronError(`The ${spec.name} field step has more than one slash.`);
|
|
24
|
+
const step = stepText === undefined ? 1 : Number(stepText);
|
|
25
|
+
if (!Number.isInteger(step) || step <= 0)
|
|
26
|
+
throw cronError(`The ${spec.name} field step is a positive integer.`);
|
|
27
|
+
let from;
|
|
28
|
+
let to;
|
|
29
|
+
if (rangeText === '*') {
|
|
30
|
+
from = spec.min;
|
|
31
|
+
to = spec.max;
|
|
32
|
+
}
|
|
33
|
+
else if (NUMBER.test(rangeText)) {
|
|
34
|
+
from = Number(rangeText);
|
|
35
|
+
// A bare number with a step names the range from that number to the field maximum.
|
|
36
|
+
to = stepText === undefined ? from : spec.max;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const range = RANGE.exec(rangeText);
|
|
40
|
+
if (range === null)
|
|
41
|
+
throw cronError(`The ${spec.name} field value ${JSON.stringify(rangeText)} is not a number, range or '*'.`);
|
|
42
|
+
from = Number(range[1]);
|
|
43
|
+
to = Number(range[2]);
|
|
44
|
+
}
|
|
45
|
+
const low = from;
|
|
46
|
+
const high = to;
|
|
47
|
+
if (low < spec.min || low > spec.max || high < spec.min || high > spec.max) {
|
|
48
|
+
throw cronError(`The ${spec.name} field allows ${spec.min}..${spec.max}, not ${from}..${to}.`);
|
|
49
|
+
}
|
|
50
|
+
if (low > high)
|
|
51
|
+
throw cronError(`The ${spec.name} field range ${from}-${to} runs backwards.`);
|
|
52
|
+
for (let value = low; value <= high; value += step)
|
|
53
|
+
values.add(WEEKDAY_ALIAS[String(value)] ?? value);
|
|
54
|
+
}
|
|
55
|
+
return [...values].sort((a, b) => a - b);
|
|
56
|
+
}
|
|
57
|
+
function cronError(message) {
|
|
58
|
+
return new OnlyneError('invalid_request', message);
|
|
59
|
+
}
|
|
60
|
+
/** Parses one five-field expression; throwing `invalid_request` names the offending field. */
|
|
61
|
+
export function parseCron(expression) {
|
|
62
|
+
if (typeof expression !== 'string')
|
|
63
|
+
throw cronError('A cron expression is a string.');
|
|
64
|
+
const parts = expression.trim().split(/\s+/);
|
|
65
|
+
if (parts.length !== FIELDS.length) {
|
|
66
|
+
throw cronError(`A cron expression has ${FIELDS.length} fields (minute hour day month weekday), not ${parts.length}.`);
|
|
67
|
+
}
|
|
68
|
+
const [minutes, hours, days, months, weekdays] = parts.map((part, index) => parseField(part, FIELDS[index]));
|
|
69
|
+
return {
|
|
70
|
+
minutes: minutes, hours: hours, days: days, months: months, weekdays: weekdays,
|
|
71
|
+
domRestricted: parts[2] !== '*',
|
|
72
|
+
dowRestricted: parts[4] !== '*',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const MINUTE_MS = 60_000;
|
|
76
|
+
const HOUR_MS = 3_600_000;
|
|
77
|
+
const DAY_MS = 86_400_000;
|
|
78
|
+
/** Five years covers every Gregorian recurrence, including 29 February on a weekday. */
|
|
79
|
+
const HORIZON_DAYS = 366 * 5;
|
|
80
|
+
/**
|
|
81
|
+
* The first instant strictly after `fromMs` that the expression admits, to the minute, in UTC.
|
|
82
|
+
* `undefined` means no occurrence inside the five-year horizon (for example `0 0 31 2 *`).
|
|
83
|
+
*/
|
|
84
|
+
export function nextCronTime(schedule, fromMs) {
|
|
85
|
+
const dayStart = Math.floor(fromMs / DAY_MS) * DAY_MS;
|
|
86
|
+
for (let day = 0; day < HORIZON_DAYS; day++) {
|
|
87
|
+
const base = dayStart + day * DAY_MS;
|
|
88
|
+
const date = new Date(base);
|
|
89
|
+
const month = date.getUTCMonth() + 1;
|
|
90
|
+
if (!schedule.months.includes(month))
|
|
91
|
+
continue;
|
|
92
|
+
const dom = date.getUTCDate();
|
|
93
|
+
const dow = date.getUTCDay();
|
|
94
|
+
const domMatch = schedule.days.includes(dom);
|
|
95
|
+
const dowMatch = schedule.weekdays.includes(dow);
|
|
96
|
+
// Vixie cron: a restricted day-of-month and a restricted day-of-week combine with OR.
|
|
97
|
+
const dayMatch = schedule.domRestricted && schedule.dowRestricted
|
|
98
|
+
? domMatch || dowMatch
|
|
99
|
+
: domMatch && dowMatch;
|
|
100
|
+
if (!dayMatch)
|
|
101
|
+
continue;
|
|
102
|
+
for (const hour of schedule.hours) {
|
|
103
|
+
for (const minute of schedule.minutes) {
|
|
104
|
+
const at = base + hour * HOUR_MS + minute * MINUTE_MS;
|
|
105
|
+
if (at > fromMs)
|
|
106
|
+
return at;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=cron.js.map
|
package/dist/cron.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"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"}
|
package/dist/exec.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Output kept per stream: enough for one readable result line, bounded so a chatty script cannot bloat the store. */
|
|
2
|
+
export declare const OUTPUT_CAP = 4096;
|
|
3
|
+
export interface CommandResult {
|
|
4
|
+
exit_code: number | null;
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
output_bytes: number;
|
|
8
|
+
}
|
|
9
|
+
export interface CommandTarget {
|
|
10
|
+
command: string;
|
|
11
|
+
args?: readonly string[];
|
|
12
|
+
cwd?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A handle the scheduler keeps so it can signal exactly the process it started, never a name match. */
|
|
15
|
+
export interface RunningChild {
|
|
16
|
+
cancelled: boolean;
|
|
17
|
+
pid?: number;
|
|
18
|
+
}
|
|
19
|
+
/** Signals the process group the scheduler built: the exact child first, then its verified descendants. */
|
|
20
|
+
export declare function signalTree(child: RunningChild, signal: NodeJS.Signals): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Stops one run: SIGTERM for a clean exit, then SIGKILL of the same subtree while its root is
|
|
23
|
+
* still alive after the grace period. The escalation is not awaited by the caller, so a cancel
|
|
24
|
+
* answers as soon as the signal is sent; the run settles when its process actually exits.
|
|
25
|
+
*/
|
|
26
|
+
export declare function stopChild(child: RunningChild): void;
|
|
27
|
+
/**
|
|
28
|
+
* Runs one allowlisted executable with argv directly, never through a shell: no quoting, no
|
|
29
|
+
* metacharacters, no remote string ever reaches `/bin/sh`. The child's pid is recorded before
|
|
30
|
+
* any output is read so a cancel that arrives first still has a handle to signal.
|
|
31
|
+
*/
|
|
32
|
+
export declare function runCommand(target: CommandTarget, child: RunningChild): Promise<CommandResult>;
|
|
33
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAEA,sHAAsH;AACtH,eAAO,MAAM,UAAU,OAAQ,CAAC;AAIhC,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wGAAwG;AACxG,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAwDD,2GAA2G;AAC3G,wBAAsB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3F;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAYnD;AAgBD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CA6BnG"}
|