@vtechcom/hexcore 2.0.0-beta.1
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/CHANGELOG.md +127 -0
- package/LICENSE +201 -0
- package/README.md +283 -0
- package/dist/app.module.js +55 -0
- package/dist/app.module.js.map +1 -0
- package/dist/auth.js +151 -0
- package/dist/auth.js.map +1 -0
- package/dist/chain/cost-models.js +81 -0
- package/dist/chain/cost-models.js.map +1 -0
- package/dist/chain/provider.js +269 -0
- package/dist/chain/provider.js.map +1 -0
- package/dist/chain/socket.js +48 -0
- package/dist/chain/socket.js.map +1 -0
- package/dist/cli/doctor.js +43 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/hexcore.js +435 -0
- package/dist/cli/hexcore.js.map +1 -0
- package/dist/common/auth.guard.js +66 -0
- package/dist/common/auth.guard.js.map +1 -0
- package/dist/common/http.js +171 -0
- package/dist/common/http.js.map +1 -0
- package/dist/common/zod-validation.pipe.js +47 -0
- package/dist/common/zod-validation.pipe.js.map +1 -0
- package/dist/config.js +354 -0
- package/dist/config.js.map +1 -0
- package/dist/config.module.js +35 -0
- package/dist/config.module.js.map +1 -0
- package/dist/controllers/cardano.controller.js +173 -0
- package/dist/controllers/cardano.controller.js.map +1 -0
- package/dist/controllers/heads.controller.js +225 -0
- package/dist/controllers/heads.controller.js.map +1 -0
- package/dist/controllers/setup.controller.js +127 -0
- package/dist/controllers/setup.controller.js.map +1 -0
- package/dist/controllers/system.controller.js +153 -0
- package/dist/controllers/system.controller.js.map +1 -0
- package/dist/db/database.module.js +73 -0
- package/dist/db/database.module.js.map +1 -0
- package/dist/db/index.js +135 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/repositories.js +220 -0
- package/dist/db/repositories.js.map +1 -0
- package/dist/docker/container-stats.js +134 -0
- package/dist/docker/container-stats.js.map +1 -0
- package/dist/docker/docker.service.js +335 -0
- package/dist/docker/docker.service.js.map +1 -0
- package/dist/hydra/argv.js +172 -0
- package/dist/hydra/argv.js.map +1 -0
- package/dist/hydra/blockfrost-keys.js +15 -0
- package/dist/hydra/blockfrost-keys.js.map +1 -0
- package/dist/hydra/boot-progress.js +165 -0
- package/dist/hydra/boot-progress.js.map +1 -0
- package/dist/hydra/capabilities.js +131 -0
- package/dist/hydra/capabilities.js.map +1 -0
- package/dist/hydra/head.service.js +1072 -0
- package/dist/hydra/head.service.js.map +1 -0
- package/dist/hydra/keys.js +301 -0
- package/dist/hydra/keys.js.map +1 -0
- package/dist/hydra/node-monitor.service.js +265 -0
- package/dist/hydra/node-monitor.service.js.map +1 -0
- package/dist/hydra/ws-client.js +177 -0
- package/dist/hydra/ws-client.js.map +1 -0
- package/dist/main.js +106 -0
- package/dist/main.js.map +1 -0
- package/dist/preflight.js +215 -0
- package/dist/preflight.js.map +1 -0
- package/dist/settings.js +243 -0
- package/dist/settings.js.map +1 -0
- package/dist/setup.service.js +257 -0
- package/dist/setup.service.js.map +1 -0
- package/dist/version.js +46 -0
- package/dist/version.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/api.d.ts +730 -0
- package/node_modules/@hexcore/shared/dist/cjs/api.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/api.js +358 -0
- package/node_modules/@hexcore/shared/dist/cjs/api.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/domain.d.ts +298 -0
- package/node_modules/@hexcore/shared/dist/cjs/domain.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/domain.js +49 -0
- package/node_modules/@hexcore/shared/dist/cjs/domain.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.d.ts +279 -0
- package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.js +453 -0
- package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/index.d.ts +7 -0
- package/node_modules/@hexcore/shared/dist/cjs/index.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/index.js +23 -0
- package/node_modules/@hexcore/shared/dist/cjs/index.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/naming.d.ts +118 -0
- package/node_modules/@hexcore/shared/dist/cjs/naming.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/naming.js +103 -0
- package/node_modules/@hexcore/shared/dist/cjs/naming.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/offline.d.ts +73 -0
- package/node_modules/@hexcore/shared/dist/cjs/offline.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/offline.js +80 -0
- package/node_modules/@hexcore/shared/dist/cjs/offline.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/protocol-params.d.ts +79 -0
- package/node_modules/@hexcore/shared/dist/cjs/protocol-params.d.ts.map +1 -0
- package/node_modules/@hexcore/shared/dist/cjs/protocol-params.js +223 -0
- package/node_modules/@hexcore/shared/dist/cjs/protocol-params.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/api.js +355 -0
- package/node_modules/@hexcore/shared/dist/esm/api.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/domain.js +46 -0
- package/node_modules/@hexcore/shared/dist/esm/domain.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/hydra-versions.js +441 -0
- package/node_modules/@hexcore/shared/dist/esm/hydra-versions.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/index.js +7 -0
- package/node_modules/@hexcore/shared/dist/esm/index.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/naming.js +95 -0
- package/node_modules/@hexcore/shared/dist/esm/naming.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/offline.js +75 -0
- package/node_modules/@hexcore/shared/dist/esm/offline.js.map +1 -0
- package/node_modules/@hexcore/shared/dist/esm/package.json +3 -0
- package/node_modules/@hexcore/shared/dist/esm/protocol-params.js +217 -0
- package/node_modules/@hexcore/shared/dist/esm/protocol-params.js.map +1 -0
- package/node_modules/@hexcore/shared/package.json +15 -0
- package/package.json +67 -0
- package/web/200.html +23 -0
- package/web/404.html +23 -0
- package/web/_nuxt/2MxohCD-.js +1 -0
- package/web/_nuxt/4pFXjB_u.js +1 -0
- package/web/_nuxt/B-v0dEQX.js +1 -0
- package/web/_nuxt/B4yE3U25.js +1 -0
- package/web/_nuxt/BFh8Ai0L.js +1 -0
- package/web/_nuxt/BgPn4NJH.js +1 -0
- package/web/_nuxt/Bj1xviSh.js +1 -0
- package/web/_nuxt/BnotlrL7.js +1 -0
- package/web/_nuxt/C1YRg2ic.js +1 -0
- package/web/_nuxt/CGD7MYQH.js +1 -0
- package/web/_nuxt/CQcG7Bu4.js +1 -0
- package/web/_nuxt/CS3KqpH_.js +1 -0
- package/web/_nuxt/CT-yt694.js +1 -0
- package/web/_nuxt/CZK6xUH-.js +1 -0
- package/web/_nuxt/CcdyYRYz.js +1 -0
- package/web/_nuxt/CePNTU1S.js +1 -0
- package/web/_nuxt/CgPLsCeU.js +5 -0
- package/web/_nuxt/CkCrahXt.js +1 -0
- package/web/_nuxt/CnOqDT9k.js +3 -0
- package/web/_nuxt/CqsSss-D.js +1 -0
- package/web/_nuxt/Cr8dL64Q.js +1 -0
- package/web/_nuxt/D3CwzwU0.js +1 -0
- package/web/_nuxt/DDANn6-H.js +1 -0
- package/web/_nuxt/DDl9uKIA.js +1 -0
- package/web/_nuxt/DL9i0ayn.js +1 -0
- package/web/_nuxt/DLNoK9BC.js +1 -0
- package/web/_nuxt/DLztFeOQ.js +1 -0
- package/web/_nuxt/DPihKXdt.js +1 -0
- package/web/_nuxt/DXyr6Naa.js +1 -0
- package/web/_nuxt/DeDg5p0D.js +1 -0
- package/web/_nuxt/DgDlQiDU.js +1 -0
- package/web/_nuxt/DyPI7qJE.js +30 -0
- package/web/_nuxt/LGfPBi70.js +1 -0
- package/web/_nuxt/Onf26W-r.js +1 -0
- package/web/_nuxt/QZNQe_OX.js +1 -0
- package/web/_nuxt/Y8IJM-iz.js +1 -0
- package/web/_nuxt/YUGC0nt0.js +1 -0
- package/web/_nuxt/builds/latest.json +1 -0
- package/web/_nuxt/builds/meta/7e461629-93e2-4694-b237-6d5c6a85c97c.json +1 -0
- package/web/_nuxt/builds/meta/dev.json +1 -0
- package/web/_nuxt/entry.BxsAxZxf.css +1 -0
- package/web/_nuxt/error-404.XbtAw-qw.css +1 -0
- package/web/_nuxt/error-500.CNHVltWM.css +1 -0
- package/web/_nuxt/rS90pPZ_.js +1 -0
- package/web/_nuxt/rhEiP908.js +1 -0
- package/web/_nuxt/vSj9Ec0g.js +1 -0
- package/web/_nuxt/woNjBJMN.js +1 -0
- package/web/favicon.svg +28 -0
- package/web/heads/index.html +23 -0
- package/web/heads/new/index.html +23 -0
- package/web/index.html +23 -0
- package/web/login/index.html +23 -0
- package/web/logo.svg +56 -0
- package/web/settings/index.html +23 -0
- package/web/setup/index.html +23 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var ApiExceptionFilter_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ApiExceptionFilter = exports.ResponseEnvelopeInterceptor = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const rxjs_1 = require("rxjs");
|
|
14
|
+
const head_service_1 = require("../hydra/head.service");
|
|
15
|
+
const docker_service_1 = require("../docker/docker.service");
|
|
16
|
+
const provider_1 = require("../chain/provider");
|
|
17
|
+
const setup_service_1 = require("../setup.service");
|
|
18
|
+
/** Wrap every successful payload in { ok: true, data } — matches ApiResponse<T>. */
|
|
19
|
+
let ResponseEnvelopeInterceptor = class ResponseEnvelopeInterceptor {
|
|
20
|
+
intercept(_ctx, next) {
|
|
21
|
+
return next.handle().pipe((0, rxjs_1.map)(data => ({ ok: true, data })));
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports.ResponseEnvelopeInterceptor = ResponseEnvelopeInterceptor;
|
|
25
|
+
exports.ResponseEnvelopeInterceptor = ResponseEnvelopeInterceptor = __decorate([
|
|
26
|
+
(0, common_1.Injectable)()
|
|
27
|
+
], ResponseEnvelopeInterceptor);
|
|
28
|
+
/**
|
|
29
|
+
* Single place that turns any thrown error into { ok: false, error }.
|
|
30
|
+
*
|
|
31
|
+
* v1 leaked raw exceptions (and occasionally stack traces) to clients because
|
|
32
|
+
* each controller handled its own failures. Here domain errors carry their own
|
|
33
|
+
* HTTP semantics and everything else becomes a clean 500.
|
|
34
|
+
*/
|
|
35
|
+
let ApiExceptionFilter = class ApiExceptionFilter {
|
|
36
|
+
static { ApiExceptionFilter_1 = this; }
|
|
37
|
+
logger = new common_1.Logger(ApiExceptionFilter_1.name);
|
|
38
|
+
/**
|
|
39
|
+
* Absolute path of the built web UI when the control-plane is also serving
|
|
40
|
+
* it, otherwise null. Set from main.ts at bootstrap.
|
|
41
|
+
*/
|
|
42
|
+
static spaIndexPath = null;
|
|
43
|
+
catch(exception, host) {
|
|
44
|
+
const http = host.switchToHttp();
|
|
45
|
+
const reply = http.getResponse();
|
|
46
|
+
const request = http.getRequest();
|
|
47
|
+
const { status, code, message, details } = this.describe(exception);
|
|
48
|
+
/**
|
|
49
|
+
* SPA deep links.
|
|
50
|
+
*
|
|
51
|
+
* /heads/3 has no file on disk, so @fastify/static misses and Nest
|
|
52
|
+
* raises a 404 that lands here. Serving index.html lets vue-router
|
|
53
|
+
* resolve the route client-side. Nest owns the not-found handler, so
|
|
54
|
+
* this filter is the only place that sees the miss.
|
|
55
|
+
*
|
|
56
|
+
* API paths must still 404 as JSON — a client fetching a bad endpoint
|
|
57
|
+
* needs an error, not a page.
|
|
58
|
+
*/
|
|
59
|
+
if (status === common_1.HttpStatus.NOT_FOUND &&
|
|
60
|
+
ApiExceptionFilter_1.spaIndexPath &&
|
|
61
|
+
request.method === 'GET' &&
|
|
62
|
+
!isApiPath(request.url)) {
|
|
63
|
+
void reply.type('text/html').send((0, node_fs_1.createReadStream)(ApiExceptionFilter_1.spaIndexPath));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (status >= 500) {
|
|
67
|
+
this.logger.error(`${code}: ${message}`, exception?.stack);
|
|
68
|
+
}
|
|
69
|
+
void reply.status(status).send({ ok: false, error: { code, message, details } });
|
|
70
|
+
}
|
|
71
|
+
describe(exception) {
|
|
72
|
+
if (exception instanceof head_service_1.HeadNotFoundError) {
|
|
73
|
+
return { status: common_1.HttpStatus.NOT_FOUND, code: 'HEAD_NOT_FOUND', message: exception.message };
|
|
74
|
+
}
|
|
75
|
+
if (exception instanceof head_service_1.HeadConflictError) {
|
|
76
|
+
return { status: common_1.HttpStatus.CONFLICT, code: 'HEAD_CONFLICT', message: exception.message };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Same envelope as a zod failure — including `details[].path` — so the
|
|
80
|
+
* create form highlights the offending field whether the rule was
|
|
81
|
+
* checkable from the payload alone or needed server state.
|
|
82
|
+
*/
|
|
83
|
+
if (exception instanceof head_service_1.HeadValidationError) {
|
|
84
|
+
return {
|
|
85
|
+
status: common_1.HttpStatus.BAD_REQUEST,
|
|
86
|
+
code: 'VALIDATION_ERROR',
|
|
87
|
+
message: exception.message,
|
|
88
|
+
details: [{ path: exception.field, message: exception.message }],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/** Same envelope as a zod failure, so the setup form highlights the field. */
|
|
92
|
+
if (exception instanceof setup_service_1.SettingsValidationError) {
|
|
93
|
+
return {
|
|
94
|
+
status: common_1.HttpStatus.BAD_REQUEST,
|
|
95
|
+
code: 'VALIDATION_ERROR',
|
|
96
|
+
message: exception.message,
|
|
97
|
+
details: [{ path: exception.field, message: exception.message }],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 403, not 401: a bad setup token is not a missing login, and answering
|
|
102
|
+
* 401 would send the UI to a sign-in screen for an installation that
|
|
103
|
+
* has no account yet.
|
|
104
|
+
*/
|
|
105
|
+
if (exception instanceof setup_service_1.SetupForbiddenError) {
|
|
106
|
+
return { status: common_1.HttpStatus.FORBIDDEN, code: 'SETUP_FORBIDDEN', message: exception.message };
|
|
107
|
+
}
|
|
108
|
+
if (exception instanceof docker_service_1.ImagePullError) {
|
|
109
|
+
// The reference is a setting someone typed, so this is their input
|
|
110
|
+
// being wrong rather than the registry misbehaving.
|
|
111
|
+
return { status: common_1.HttpStatus.BAD_REQUEST, code: 'IMAGE_PULL_FAILED', message: exception.message };
|
|
112
|
+
}
|
|
113
|
+
if (exception instanceof docker_service_1.DockerUnavailableError) {
|
|
114
|
+
return { status: common_1.HttpStatus.SERVICE_UNAVAILABLE, code: 'DOCKER_UNAVAILABLE', message: exception.message };
|
|
115
|
+
}
|
|
116
|
+
if (exception instanceof provider_1.ChainProviderError) {
|
|
117
|
+
return { status: common_1.HttpStatus.BAD_GATEWAY, code: 'CHAIN_PROVIDER_ERROR', message: exception.message };
|
|
118
|
+
}
|
|
119
|
+
if (exception instanceof common_1.HttpException) {
|
|
120
|
+
const res = exception.getResponse();
|
|
121
|
+
if (typeof res === 'object' && res !== null && 'code' in res) {
|
|
122
|
+
const body = res;
|
|
123
|
+
return {
|
|
124
|
+
status: exception.getStatus(),
|
|
125
|
+
code: body.code,
|
|
126
|
+
message: body.message ?? exception.message,
|
|
127
|
+
details: body.details,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
status: exception.getStatus(),
|
|
132
|
+
code: httpCodeName(exception.getStatus()),
|
|
133
|
+
message: typeof res === 'string' ? res : exception.message,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
status: common_1.HttpStatus.INTERNAL_SERVER_ERROR,
|
|
138
|
+
code: 'INTERNAL_ERROR',
|
|
139
|
+
message: exception?.message ?? 'Unexpected error',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
exports.ApiExceptionFilter = ApiExceptionFilter;
|
|
144
|
+
exports.ApiExceptionFilter = ApiExceptionFilter = ApiExceptionFilter_1 = __decorate([
|
|
145
|
+
(0, common_1.Catch)()
|
|
146
|
+
], ApiExceptionFilter);
|
|
147
|
+
/**
|
|
148
|
+
* Paths that must always answer with JSON, never the SPA shell.
|
|
149
|
+
* Kept in one place so the filter and any future middleware agree.
|
|
150
|
+
*/
|
|
151
|
+
function isApiPath(url) {
|
|
152
|
+
const path = url.split('?')[0] ?? '';
|
|
153
|
+
return path.startsWith('/api') || path === '/health' || path.startsWith('/api-docs');
|
|
154
|
+
}
|
|
155
|
+
function httpCodeName(status) {
|
|
156
|
+
switch (status) {
|
|
157
|
+
case 400:
|
|
158
|
+
return 'BAD_REQUEST';
|
|
159
|
+
case 401:
|
|
160
|
+
return 'UNAUTHORIZED';
|
|
161
|
+
case 403:
|
|
162
|
+
return 'FORBIDDEN';
|
|
163
|
+
case 404:
|
|
164
|
+
return 'NOT_FOUND';
|
|
165
|
+
case 409:
|
|
166
|
+
return 'CONFLICT';
|
|
167
|
+
default:
|
|
168
|
+
return 'ERROR';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/common/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ZodValidationPipe = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
/**
|
|
15
|
+
* Validate a request body/query with a zod schema from @hexcore/shared.
|
|
16
|
+
*
|
|
17
|
+
* This is what lets v2 keep ONE definition of every payload: the same schema
|
|
18
|
+
* validates on the server and types the fetch call in the Nuxt UI. With
|
|
19
|
+
* class-validator DTOs (v1) the frontend had to redeclare each shape by hand,
|
|
20
|
+
* and the two drifted — several v1 UI bugs were payloads the API had changed.
|
|
21
|
+
*/
|
|
22
|
+
let ZodValidationPipe = class ZodValidationPipe {
|
|
23
|
+
schema;
|
|
24
|
+
constructor(schema) {
|
|
25
|
+
this.schema = schema;
|
|
26
|
+
}
|
|
27
|
+
transform(value) {
|
|
28
|
+
const result = this.schema.safeParse(value);
|
|
29
|
+
if (!result.success) {
|
|
30
|
+
throw new common_1.BadRequestException({
|
|
31
|
+
code: 'VALIDATION_ERROR',
|
|
32
|
+
message: 'Request payload failed validation',
|
|
33
|
+
details: result.error.issues.map(i => ({
|
|
34
|
+
path: i.path.join('.') || '(root)',
|
|
35
|
+
message: i.message,
|
|
36
|
+
})),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return result.data;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.ZodValidationPipe = ZodValidationPipe;
|
|
43
|
+
exports.ZodValidationPipe = ZodValidationPipe = __decorate([
|
|
44
|
+
(0, common_1.Injectable)(),
|
|
45
|
+
__metadata("design:paramtypes", [Function])
|
|
46
|
+
], ZodValidationPipe);
|
|
47
|
+
//# sourceMappingURL=zod-validation.pipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-validation.pipe.js","sourceRoot":"","sources":["../../src/common/zod-validation.pipe.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAqF;AAGrF;;;;;;;GAOG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IACG;IAA7B,YAA6B,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAElD,SAAS,CAAC,KAAc;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,4BAAmB,CAAC;gBAC1B,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,mCAAmC;gBAC5C,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACnC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ;oBAClC,OAAO,EAAE,CAAC,CAAC,OAAO;iBACrB,CAAC,CAAC;aACN,CAAC,CAAC;QACP,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACvB,CAAC;CACJ,CAAA;AAjBY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;;GACA,iBAAiB,CAiB7B"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigError = exports.dotenvFound = void 0;
|
|
4
|
+
exports.currentLayers = currentLayers;
|
|
5
|
+
exports.loadConfig = loadConfig;
|
|
6
|
+
exports.describeProvenance = describeProvenance;
|
|
7
|
+
exports.getConfig = getConfig;
|
|
8
|
+
exports.reloadConfigInto = reloadConfigInto;
|
|
9
|
+
/**
|
|
10
|
+
* Configuration.
|
|
11
|
+
*
|
|
12
|
+
* v1 required ~30 environment variables with no validation — a typo surfaced as
|
|
13
|
+
* an undefined deep inside a Docker call. v2 validates everything on boot with
|
|
14
|
+
* zod and defaults hard enough that it runs with no configuration at all.
|
|
15
|
+
*
|
|
16
|
+
* Values arrive in four layers, highest first: a real environment variable, a
|
|
17
|
+
* `.env` in the current directory, the settings file the setup wizard writes,
|
|
18
|
+
* then the defaults below. `settings.ts` owns that merge and can explain where
|
|
19
|
+
* any given value came from — see `describeProvenance`.
|
|
20
|
+
*/
|
|
21
|
+
const zod_1 = require("zod");
|
|
22
|
+
const dotenv_1 = require("dotenv");
|
|
23
|
+
const node_fs_1 = require("node:fs");
|
|
24
|
+
const node_path_1 = require("node:path");
|
|
25
|
+
const settings_1 = require("./settings");
|
|
26
|
+
/**
|
|
27
|
+
* The environment as it was BEFORE dotenv ran.
|
|
28
|
+
*
|
|
29
|
+
* Taken at module load and never recomputed. dotenv assigns into `process.env`
|
|
30
|
+
* without overwriting, so once it has run there is no way to tell a variable
|
|
31
|
+
* the operator exported from one a `.env` supplied — and that difference is
|
|
32
|
+
* exactly what `hexcore config` has to report.
|
|
33
|
+
*/
|
|
34
|
+
const REAL_ENV = { ...process.env };
|
|
35
|
+
const DOTENV_VALUES = (0, dotenv_1.config)({ quiet: true }).parsed ?? {};
|
|
36
|
+
/** Whether a `.env` was found in the current directory, which counts as setup. */
|
|
37
|
+
exports.dotenvFound = (0, node_fs_1.existsSync)((0, node_path_1.resolve)(process.cwd(), '.env'));
|
|
38
|
+
/** The layers as this process sees them. */
|
|
39
|
+
function currentLayers() {
|
|
40
|
+
// HEXCORE_HOME decides where the settings file is, so it can only come from
|
|
41
|
+
// the two layers above it.
|
|
42
|
+
const forHome = { ...DOTENV_VALUES, ...definedOnly(REAL_ENV) };
|
|
43
|
+
return { environment: REAL_ENV, dotenv: DOTENV_VALUES, file: (0, settings_1.readSettings)(forHome).env };
|
|
44
|
+
}
|
|
45
|
+
function definedOnly(env) {
|
|
46
|
+
const out = {};
|
|
47
|
+
for (const [key, value] of Object.entries(env)) {
|
|
48
|
+
if (value !== undefined && value !== '')
|
|
49
|
+
out[key] = value;
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
const bool = (def) => zod_1.z
|
|
54
|
+
.string()
|
|
55
|
+
.optional()
|
|
56
|
+
.transform(v => (v === undefined || v === '' ? def : v === 'true' || v === '1'));
|
|
57
|
+
const int = (def) => zod_1.z
|
|
58
|
+
.string()
|
|
59
|
+
.optional()
|
|
60
|
+
.transform(v => (v === undefined || v === '' ? def : Number(v)))
|
|
61
|
+
.pipe(zod_1.z.number().int());
|
|
62
|
+
/**
|
|
63
|
+
* An integer with no default, so "unset" stays distinguishable from a value
|
|
64
|
+
* that happens to equal the default. Used for the knobs whose real default
|
|
65
|
+
* comes from the hydra-node version profile — baking one in here would mean an
|
|
66
|
+
* operator who never touched .env silently overriding every future version.
|
|
67
|
+
*/
|
|
68
|
+
const optInt = () => zod_1.z
|
|
69
|
+
.string()
|
|
70
|
+
.optional()
|
|
71
|
+
.transform(v => (v === undefined || v === '' ? undefined : Number(v)))
|
|
72
|
+
.pipe(zod_1.z.number().int().optional());
|
|
73
|
+
const envSchema = zod_1.z
|
|
74
|
+
.object({
|
|
75
|
+
NODE_ENV: zod_1.z.enum(['development', 'production', 'test']).default('development'),
|
|
76
|
+
PORT: int(4000),
|
|
77
|
+
HOST: zod_1.z.string().default('0.0.0.0'),
|
|
78
|
+
LOG_LEVEL: zod_1.z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),
|
|
79
|
+
/**
|
|
80
|
+
* Root for all mutable state: sqlite db, keys, persistence dirs.
|
|
81
|
+
*
|
|
82
|
+
* No default here on purpose — see `defaultStateDir`, which has to
|
|
83
|
+
* adopt an existing `./.hexcore` before falling back to the home, or a
|
|
84
|
+
* running installation's signing keys would appear to vanish.
|
|
85
|
+
*/
|
|
86
|
+
STATE_DIR: zod_1.z.string().optional(),
|
|
87
|
+
CARDANO_NETWORK: zod_1.z.enum(['preprod', 'preview', 'mainnet']).default('preprod'),
|
|
88
|
+
/**
|
|
89
|
+
* Default backend for heads that name none. `offline` runs hydra-node
|
|
90
|
+
* with its layer-1 interface disabled — no key, no socket, no chain —
|
|
91
|
+
* which is the useful default on a dev machine with neither credential.
|
|
92
|
+
*/
|
|
93
|
+
CHAIN_BACKEND: zod_1.z.enum(['blockfrost', 'cardano-node', 'offline']).default('blockfrost'),
|
|
94
|
+
BLOCKFROST_PROJECT_ID: zod_1.z.string().optional(),
|
|
95
|
+
BLOCKFROST_BASE_URL: zod_1.z.string().optional(),
|
|
96
|
+
/**
|
|
97
|
+
* Blockfrost is an HTTP poller, not a chain follower, so a node's view
|
|
98
|
+
* of the tip lags. Upstream measured 50-80s of drift on preprod against
|
|
99
|
+
* ~0s for a local socket.
|
|
100
|
+
*
|
|
101
|
+
* That matters because hydra-node treats an unsynced node as unusable:
|
|
102
|
+
* past --unsynced-period it stops signing snapshots AND rejects client
|
|
103
|
+
* input. The flag defaults to half the contestation period, so a 120s
|
|
104
|
+
* contestation gives 60s — inside the drift band, and the node flips
|
|
105
|
+
* unsynced mid-operation.
|
|
106
|
+
*
|
|
107
|
+
* 180s is upstream's tested value: it absorbs the drift while still
|
|
108
|
+
* catching a genuinely stalled node.
|
|
109
|
+
*
|
|
110
|
+
* Left unset, the value comes from the head's hydra-node version
|
|
111
|
+
* profile (HYDRA_VERSION_PROFILES in @hexcore/shared). Set here it wins
|
|
112
|
+
* over the profile for every head, on every version.
|
|
113
|
+
*/
|
|
114
|
+
HYDRA_UNSYNCED_PERIOD: optInt(),
|
|
115
|
+
/** Per-query and total-retry budgets for the Blockfrost backend. Same precedence. */
|
|
116
|
+
BLOCKFROST_QUERY_TIMEOUT: optInt(),
|
|
117
|
+
BLOCKFROST_RETRY_TIMEOUT: optInt(),
|
|
118
|
+
/** Only used when CHAIN_BACKEND=cardano-node. */
|
|
119
|
+
CARDANO_NODE_SOCKET: zod_1.z.string().optional(),
|
|
120
|
+
/**
|
|
121
|
+
* Default pinned to the 2.x line.
|
|
122
|
+
*
|
|
123
|
+
* 2.x is what makes the Blockfrost backend actually dependable: the
|
|
124
|
+
* drift-tolerance flags (--unsynced-period, --blockfrost-*-timeout)
|
|
125
|
+
* simply do not exist on 0.22.x, so on that image a Blockfrost head
|
|
126
|
+
* runs with a 60s unsynced budget inside a 50-80s drift band and can
|
|
127
|
+
* stop signing snapshots mid-operation.
|
|
128
|
+
*
|
|
129
|
+
* Older images still work — every version this build supports declares
|
|
130
|
+
* its flag set in HYDRA_VERSION_PROFILES, and anything else is probed
|
|
131
|
+
* (see capabilities.ts) — but they do not get that protection.
|
|
132
|
+
*
|
|
133
|
+
* This is only the default. A create request may name a different
|
|
134
|
+
* image per head, which is how two versions run side by side.
|
|
135
|
+
*
|
|
136
|
+
* Note 2.x is a protocol change, not just a version bump: no commit
|
|
137
|
+
* phase (ADR-33), HydraHeadV2 identity token, SQLite event store, and
|
|
138
|
+
* new script hashes per network. Heads created against 0.22.x are not
|
|
139
|
+
* resumable on 2.x; reset them before switching.
|
|
140
|
+
*/
|
|
141
|
+
HYDRA_NODE_IMAGE: zod_1.z.string().default('ghcr.io/cardano-scaling/hydra-node:2.3.0'),
|
|
142
|
+
/**
|
|
143
|
+
* Comma-separated script tx ids. Left empty the node publishes/uses its
|
|
144
|
+
* own — v1 forced you to hunt these down per version/network before
|
|
145
|
+
* anything would boot.
|
|
146
|
+
*/
|
|
147
|
+
HYDRA_SCRIPTS_TX_ID: zod_1.z.string().optional(),
|
|
148
|
+
DOCKER_SOCKET: zod_1.z.string().default('/var/run/docker.sock'),
|
|
149
|
+
PORT_BASE: int(14000),
|
|
150
|
+
MAX_ACTIVE_NODES: int(20),
|
|
151
|
+
ADMIN_USERNAME: zod_1.z.string().default('admin'),
|
|
152
|
+
ADMIN_PASSWORD: zod_1.z.string().optional(),
|
|
153
|
+
/** Generated + persisted on first boot when unset. */
|
|
154
|
+
JWT_SECRET: zod_1.z.string().optional(),
|
|
155
|
+
AUTH_ENABLED: bool(true),
|
|
156
|
+
CORS_ORIGIN: zod_1.z.string().default('*'),
|
|
157
|
+
/** Serve the built web UI from the control-plane (single-process mode). */
|
|
158
|
+
SERVE_WEB: bool(false),
|
|
159
|
+
WEB_DIST: zod_1.z.string().optional(),
|
|
160
|
+
})
|
|
161
|
+
.superRefine((v, ctx) => {
|
|
162
|
+
/**
|
|
163
|
+
* Neither backend's credential is required to boot any more.
|
|
164
|
+
*
|
|
165
|
+
* A server-wide BLOCKFROST_PROJECT_ID is now only a DEFAULT: a head — or
|
|
166
|
+
* an individual node — can carry its own key, so an operator who keys
|
|
167
|
+
* every head separately has nothing to put here. Refusing to start over
|
|
168
|
+
* a missing default would make that setup impossible to run.
|
|
169
|
+
*
|
|
170
|
+
* What is still checked is a key that cannot work: see the network
|
|
171
|
+
* prefix rule below.
|
|
172
|
+
*/
|
|
173
|
+
/**
|
|
174
|
+
* A Blockfrost project id is network-scoped and its prefix says which
|
|
175
|
+
* network it is for. Catch a mismatch here: left to hydra-node it
|
|
176
|
+
* surfaces much later, deep inside chain observation, as a confusing
|
|
177
|
+
* "cannot find script" or a head that simply never observes its own
|
|
178
|
+
* init transaction.
|
|
179
|
+
*/
|
|
180
|
+
if (v.BLOCKFROST_PROJECT_ID && !v.BLOCKFROST_PROJECT_ID.startsWith(v.CARDANO_NETWORK)) {
|
|
181
|
+
const prefix = v.BLOCKFROST_PROJECT_ID.slice(0, 7);
|
|
182
|
+
ctx.addIssue({
|
|
183
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
184
|
+
path: ['BLOCKFROST_PROJECT_ID'],
|
|
185
|
+
message: `BLOCKFROST_PROJECT_ID starts with "${prefix}…" but CARDANO_NETWORK is ` +
|
|
186
|
+
`"${v.CARDANO_NETWORK}". The project id must begin with the network name ` +
|
|
187
|
+
`(e.g. ${v.CARDANO_NETWORK}XXXXXXXX). Either use a ${v.CARDANO_NETWORK} key ` +
|
|
188
|
+
'or change CARDANO_NETWORK to match the one you have.',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* A missing CARDANO_NODE_SOCKET is deliberately NOT fatal, even with
|
|
193
|
+
* CHAIN_BACKEND=cardano-node.
|
|
194
|
+
*
|
|
195
|
+
* Refusing to boot took the whole control-plane down over one unusable
|
|
196
|
+
* backend, when the other one needs nothing but an API key. The socket
|
|
197
|
+
* is now a capability the server reports (GET /api/system/config): heads
|
|
198
|
+
* that would need it cannot be created, and the UI steers people to
|
|
199
|
+
* Blockfrost instead of leaving them with a process that won't start.
|
|
200
|
+
*/
|
|
201
|
+
});
|
|
202
|
+
/**
|
|
203
|
+
* The built UI, when this build ships one.
|
|
204
|
+
*
|
|
205
|
+
* Two shapes to cover. Installed from npm, `dist/main.js` sits beside a `web/`
|
|
206
|
+
* directory in the same package. In the monorepo it is two packages over. The
|
|
207
|
+
* first that exists wins; neither existing is fine, since SERVE_WEB is off by
|
|
208
|
+
* default and an API-only deployment is legitimate.
|
|
209
|
+
*/
|
|
210
|
+
function findWebDist() {
|
|
211
|
+
const packaged = (0, node_path_1.resolve)(__dirname, '../web');
|
|
212
|
+
if ((0, node_fs_1.existsSync)(packaged))
|
|
213
|
+
return packaged;
|
|
214
|
+
return (0, node_path_1.resolve)(process.cwd(), '../web/.output/public');
|
|
215
|
+
}
|
|
216
|
+
function buildConfig(env) {
|
|
217
|
+
const stateDir = env.STATE_DIR ? (0, settings_1.absolute)(env.STATE_DIR) : (0, settings_1.defaultStateDir)();
|
|
218
|
+
const blockfrostBaseUrl = env.BLOCKFROST_BASE_URL ??
|
|
219
|
+
(env.CARDANO_NETWORK === 'mainnet'
|
|
220
|
+
? 'https://cardano-mainnet.blockfrost.io/api/v0'
|
|
221
|
+
: `https://cardano-${env.CARDANO_NETWORK}.blockfrost.io/api/v0`);
|
|
222
|
+
return {
|
|
223
|
+
env: env.NODE_ENV,
|
|
224
|
+
isProd: env.NODE_ENV === 'production',
|
|
225
|
+
port: env.PORT,
|
|
226
|
+
host: env.HOST,
|
|
227
|
+
logLevel: env.LOG_LEVEL,
|
|
228
|
+
stateDir,
|
|
229
|
+
dbPath: `${stateDir}/hexcore.db`,
|
|
230
|
+
headsDir: `${stateDir}/heads`,
|
|
231
|
+
secretsPath: `${stateDir}/secrets.json`,
|
|
232
|
+
network: env.CARDANO_NETWORK,
|
|
233
|
+
chainBackend: env.CHAIN_BACKEND,
|
|
234
|
+
blockfrostProjectId: env.BLOCKFROST_PROJECT_ID ?? '',
|
|
235
|
+
blockfrostBaseUrl,
|
|
236
|
+
cardanoNodeSocket: env.CARDANO_NODE_SOCKET ? (0, settings_1.absolute)(env.CARDANO_NODE_SOCKET) : '',
|
|
237
|
+
/**
|
|
238
|
+
* Operator overrides for the version-profile argv defaults. Undefined
|
|
239
|
+
* keys mean "whatever this head's hydra-node version declares"; see
|
|
240
|
+
* resolveHydraArgs in @hexcore/shared for the merge.
|
|
241
|
+
*/
|
|
242
|
+
hydraArgOverrides: {
|
|
243
|
+
unsyncedPeriod: env.HYDRA_UNSYNCED_PERIOD,
|
|
244
|
+
blockfrostQueryTimeout: env.BLOCKFROST_QUERY_TIMEOUT,
|
|
245
|
+
blockfrostRetryTimeout: env.BLOCKFROST_RETRY_TIMEOUT,
|
|
246
|
+
},
|
|
247
|
+
/** Image a head gets when the create request names none. */
|
|
248
|
+
hydraNodeImage: env.HYDRA_NODE_IMAGE,
|
|
249
|
+
hydraScriptsTxId: env.HYDRA_SCRIPTS_TX_ID?.trim() || '',
|
|
250
|
+
dockerSocket: env.DOCKER_SOCKET,
|
|
251
|
+
portBase: env.PORT_BASE,
|
|
252
|
+
maxActiveNodes: env.MAX_ACTIVE_NODES,
|
|
253
|
+
adminUsername: env.ADMIN_USERNAME,
|
|
254
|
+
adminPassword: env.ADMIN_PASSWORD ?? '',
|
|
255
|
+
jwtSecret: env.JWT_SECRET ?? '',
|
|
256
|
+
authEnabled: env.AUTH_ENABLED,
|
|
257
|
+
corsOrigin: env.CORS_ORIGIN,
|
|
258
|
+
serveWeb: env.SERVE_WEB,
|
|
259
|
+
webDist: env.WEB_DIST ? (0, settings_1.absolute)(env.WEB_DIST) : findWebDist(),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
class ConfigError extends Error {
|
|
263
|
+
issues;
|
|
264
|
+
constructor(issues) {
|
|
265
|
+
super('Invalid configuration:\n' +
|
|
266
|
+
issues.map(i => ` - ${i.path.join('.') || '(root)'}: ${i.message}`).join('\n'));
|
|
267
|
+
this.issues = issues;
|
|
268
|
+
this.name = 'ConfigError';
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
exports.ConfigError = ConfigError;
|
|
272
|
+
/**
|
|
273
|
+
* Build the running configuration.
|
|
274
|
+
*
|
|
275
|
+
* Called with no argument it merges the four layers. Called with an explicit
|
|
276
|
+
* source it parses exactly that, which is what the tests use — and what a
|
|
277
|
+
* caller wants when it is holding a hypothetical set of settings rather than
|
|
278
|
+
* the live ones.
|
|
279
|
+
*/
|
|
280
|
+
function loadConfig(source) {
|
|
281
|
+
const parsed = envSchema.safeParse(source ?? (0, settings_1.mergeLayers)(currentLayers()));
|
|
282
|
+
if (!parsed.success)
|
|
283
|
+
throw new ConfigError(parsed.error.issues);
|
|
284
|
+
return buildConfig(parsed.data);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Every setting, its value, and which layer supplied it.
|
|
288
|
+
*
|
|
289
|
+
* The point of this is `hexcore config`. Layered configuration fails in one
|
|
290
|
+
* characteristic way — a value is not wrong, it is unexplainable — and the fix
|
|
291
|
+
* is not fewer layers, it is being able to name the one that won.
|
|
292
|
+
*/
|
|
293
|
+
function describeProvenance() {
|
|
294
|
+
const layers = currentLayers();
|
|
295
|
+
const config = loadConfig((0, settings_1.mergeLayers)(layers));
|
|
296
|
+
/**
|
|
297
|
+
* The EFFECTIVE value, not the raw one.
|
|
298
|
+
*
|
|
299
|
+
* Reading it back off the built config rather than out of the merged
|
|
300
|
+
* environment matters for every key nobody has set: the raw view has
|
|
301
|
+
* nothing to show there, and a report that prints "—" next to "default" is
|
|
302
|
+
* telling the reader the one thing they already knew. What they came for is
|
|
303
|
+
* what the default actually is.
|
|
304
|
+
*/
|
|
305
|
+
return REPORTED_KEYS.map(({ key, read }) => {
|
|
306
|
+
const value = read(config);
|
|
307
|
+
return {
|
|
308
|
+
key,
|
|
309
|
+
value: value === '' ? null : value,
|
|
310
|
+
secret: settings_1.SECRET_KEYS.has(key),
|
|
311
|
+
source: (0, settings_1.sourceOf)(key, layers),
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/** Keys worth printing, and how to read each one back off the built config. */
|
|
316
|
+
const REPORTED_KEYS = [
|
|
317
|
+
{ key: 'CARDANO_NETWORK', read: c => c.network },
|
|
318
|
+
{ key: 'CHAIN_BACKEND', read: c => c.chainBackend },
|
|
319
|
+
{ key: 'BLOCKFROST_PROJECT_ID', read: c => c.blockfrostProjectId },
|
|
320
|
+
{ key: 'CARDANO_NODE_SOCKET', read: c => c.cardanoNodeSocket },
|
|
321
|
+
{ key: 'HYDRA_NODE_IMAGE', read: c => c.hydraNodeImage },
|
|
322
|
+
{ key: 'STATE_DIR', read: c => c.stateDir },
|
|
323
|
+
{ key: 'PORT', read: c => String(c.port) },
|
|
324
|
+
{ key: 'HOST', read: c => c.host },
|
|
325
|
+
{ key: 'PORT_BASE', read: c => String(c.portBase) },
|
|
326
|
+
{ key: 'DOCKER_SOCKET', read: c => c.dockerSocket },
|
|
327
|
+
{ key: 'ADMIN_USERNAME', read: c => c.adminUsername },
|
|
328
|
+
{ key: 'AUTH_ENABLED', read: c => String(c.authEnabled) },
|
|
329
|
+
{ key: 'SERVE_WEB', read: c => String(c.serveWeb) },
|
|
330
|
+
];
|
|
331
|
+
let cached = null;
|
|
332
|
+
function getConfig() {
|
|
333
|
+
if (!cached)
|
|
334
|
+
cached = loadConfig();
|
|
335
|
+
return cached;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Re-read the layers into the SAME config object.
|
|
339
|
+
*
|
|
340
|
+
* Mutation rather than replacement is the point: every service holds the object
|
|
341
|
+
* that was injected as `APP_CONFIG`, so handing back a new one would leave them
|
|
342
|
+
* all reading the old settings. This is what lets the setup wizard take effect
|
|
343
|
+
* without a restart.
|
|
344
|
+
*
|
|
345
|
+
* Values captured at construction do NOT move — the Docker client is built from
|
|
346
|
+
* `dockerSocket` once, the HTTP server is bound to `port` once. Those keys are
|
|
347
|
+
* therefore kept out of the wizard entirely rather than offered and quietly
|
|
348
|
+
* ignored; see `settingsSchema` in @hexcore/shared.
|
|
349
|
+
*/
|
|
350
|
+
function reloadConfigInto(target) {
|
|
351
|
+
Object.assign(target, loadConfig());
|
|
352
|
+
return target;
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ConfigModule = exports.APP_CONFIG = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const config_1 = require("./config");
|
|
12
|
+
/** DI token for the validated, frozen application configuration. */
|
|
13
|
+
exports.APP_CONFIG = 'APP_CONFIG';
|
|
14
|
+
/**
|
|
15
|
+
* Config is resolved once at process start (so a bad .env fails before Nest
|
|
16
|
+
* builds the module graph) and exposed globally — every other module injects
|
|
17
|
+
* APP_CONFIG rather than reading process.env, which is what made v1's
|
|
18
|
+
* configuration so hard to follow.
|
|
19
|
+
*/
|
|
20
|
+
let ConfigModule = class ConfigModule {
|
|
21
|
+
};
|
|
22
|
+
exports.ConfigModule = ConfigModule;
|
|
23
|
+
exports.ConfigModule = ConfigModule = __decorate([
|
|
24
|
+
(0, common_1.Global)(),
|
|
25
|
+
(0, common_1.Module)({
|
|
26
|
+
providers: [
|
|
27
|
+
{
|
|
28
|
+
provide: exports.APP_CONFIG,
|
|
29
|
+
useFactory: () => (0, config_1.loadConfig)(),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
exports: [exports.APP_CONFIG],
|
|
33
|
+
})
|
|
34
|
+
], ConfigModule);
|
|
35
|
+
//# sourceMappingURL=config.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.module.js","sourceRoot":"","sources":["../src/config.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAChD,qCAAsD;AAEtD,oEAAoE;AACvD,QAAA,UAAU,GAAG,YAAY,CAAC;AAEvC;;;;;GAKG;AAWI,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IAVxB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACJ,SAAS,EAAE;YACP;gBACI,OAAO,EAAE,kBAAU;gBACnB,UAAU,EAAE,GAAc,EAAE,CAAC,IAAA,mBAAU,GAAE;aAC5C;SACJ;QACD,OAAO,EAAE,CAAC,kBAAU,CAAC;KACxB,CAAC;GACW,YAAY,CAAG"}
|