@twin.org/api-service 0.0.2-next.9 → 0.0.3-next.10
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/dist/es/index.js +8 -0
- package/dist/es/index.js.map +1 -0
- package/dist/{esm/index.mjs → es/informationRoutes.js} +80 -187
- package/dist/es/informationRoutes.js.map +1 -0
- package/dist/es/informationService.js +196 -0
- package/dist/es/informationService.js.map +1 -0
- package/dist/es/models/IInformationServiceConfig.js +2 -0
- package/dist/es/models/IInformationServiceConfig.js.map +1 -0
- package/dist/es/models/IInformationServiceConstructorOptions.js +2 -0
- package/dist/es/models/IInformationServiceConstructorOptions.js.map +1 -0
- package/dist/es/restEntryPoints.js +10 -0
- package/dist/es/restEntryPoints.js.map +1 -0
- package/dist/types/index.d.ts +5 -5
- package/dist/types/informationRoutes.d.ts +9 -1
- package/dist/types/informationService.d.ts +16 -4
- package/dist/types/models/IInformationServiceConstructorOptions.d.ts +1 -1
- package/docs/changelog.md +221 -0
- package/docs/reference/classes/InformationService.md +51 -7
- package/docs/reference/functions/serverLivez.md +31 -0
- package/docs/reference/index.md +1 -0
- package/package.json +23 -9
- package/dist/cjs/index.cjs +0 -447
package/dist/cjs/index.cjs
DELETED
|
@@ -1,447 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var core = require('@twin.org/core');
|
|
4
|
-
var web = require('@twin.org/web');
|
|
5
|
-
var promises = require('node:fs/promises');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* The tag to associate with the routes.
|
|
9
|
-
*/
|
|
10
|
-
const tagsInformation = [
|
|
11
|
-
{
|
|
12
|
-
name: "Info",
|
|
13
|
-
description: "Information endpoints for the REST server."
|
|
14
|
-
}
|
|
15
|
-
];
|
|
16
|
-
/**
|
|
17
|
-
* The REST routes for server information.
|
|
18
|
-
* @param baseRouteName Prefix to prepend to the paths.
|
|
19
|
-
* @param componentName The name of the component to use in the routes stored in the ComponentFactory.
|
|
20
|
-
* @returns The generated routes.
|
|
21
|
-
*/
|
|
22
|
-
function generateRestRoutesInformation(baseRouteName, componentName) {
|
|
23
|
-
const rootRoute = {
|
|
24
|
-
operationId: "serverRoot",
|
|
25
|
-
summary: "Get the root text page",
|
|
26
|
-
tag: tagsInformation[0].name,
|
|
27
|
-
method: "GET",
|
|
28
|
-
path: `${baseRouteName}/`,
|
|
29
|
-
handler: async (httpRequestContext, request) => serverRoot(httpRequestContext, componentName),
|
|
30
|
-
responseType: [
|
|
31
|
-
{
|
|
32
|
-
type: "IServerRootResponse",
|
|
33
|
-
mimeType: web.MimeTypes.PlainText,
|
|
34
|
-
examples: [
|
|
35
|
-
{
|
|
36
|
-
id: "serverRootResponse",
|
|
37
|
-
description: "The response for the root request.",
|
|
38
|
-
response: {
|
|
39
|
-
body: "API Server - 1.0.0"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
}
|
|
44
|
-
],
|
|
45
|
-
skipAuth: true
|
|
46
|
-
};
|
|
47
|
-
const informationRoute = {
|
|
48
|
-
operationId: "serverInformation",
|
|
49
|
-
summary: "Get the information for the server",
|
|
50
|
-
tag: tagsInformation[0].name,
|
|
51
|
-
method: "GET",
|
|
52
|
-
path: `${baseRouteName}/info`,
|
|
53
|
-
handler: async (httpRequestContext, request) => serverInfo(httpRequestContext, componentName),
|
|
54
|
-
responseType: [
|
|
55
|
-
{
|
|
56
|
-
type: "IServerInfoResponse",
|
|
57
|
-
examples: [
|
|
58
|
-
{
|
|
59
|
-
id: "informationResponse",
|
|
60
|
-
description: "The response for the information request.",
|
|
61
|
-
response: {
|
|
62
|
-
body: {
|
|
63
|
-
name: "API Server",
|
|
64
|
-
version: "1.0.0"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
]
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
skipAuth: true
|
|
72
|
-
};
|
|
73
|
-
const favIconRoute = {
|
|
74
|
-
operationId: "serverFavIcon",
|
|
75
|
-
summary: "Get the favicon for the server",
|
|
76
|
-
tag: tagsInformation[0].name,
|
|
77
|
-
method: "GET",
|
|
78
|
-
path: `${baseRouteName}/favicon.ico`,
|
|
79
|
-
handler: async (httpRequestContext, request) => serverFavIcon(httpRequestContext, componentName),
|
|
80
|
-
responseType: [
|
|
81
|
-
{
|
|
82
|
-
type: "IServerFavIconResponse",
|
|
83
|
-
mimeType: "image/x-icon"
|
|
84
|
-
}
|
|
85
|
-
],
|
|
86
|
-
skipAuth: true
|
|
87
|
-
};
|
|
88
|
-
const healthRoute = {
|
|
89
|
-
operationId: "serverHealth",
|
|
90
|
-
summary: "Get the health for the server",
|
|
91
|
-
tag: tagsInformation[0].name,
|
|
92
|
-
method: "GET",
|
|
93
|
-
path: `${baseRouteName}/health`,
|
|
94
|
-
handler: async (httpRequestContext, request) => serverHealth(httpRequestContext, componentName),
|
|
95
|
-
responseType: [
|
|
96
|
-
{
|
|
97
|
-
type: "IServerHealthResponse",
|
|
98
|
-
examples: [
|
|
99
|
-
{
|
|
100
|
-
id: "healthResponseOK",
|
|
101
|
-
description: "The response for the health request.",
|
|
102
|
-
response: {
|
|
103
|
-
body: {
|
|
104
|
-
status: "ok",
|
|
105
|
-
components: [
|
|
106
|
-
{
|
|
107
|
-
name: "Database",
|
|
108
|
-
status: "ok"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
name: "Storage",
|
|
112
|
-
status: "ok"
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
id: "healthResponseWarning",
|
|
120
|
-
description: "The response for the health request with warnings.",
|
|
121
|
-
response: {
|
|
122
|
-
body: {
|
|
123
|
-
status: "warning",
|
|
124
|
-
components: [
|
|
125
|
-
{
|
|
126
|
-
name: "Database",
|
|
127
|
-
status: "warning",
|
|
128
|
-
details: "The database is running slow."
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
name: "Storage",
|
|
132
|
-
status: "ok"
|
|
133
|
-
}
|
|
134
|
-
]
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
id: "healthResponseError",
|
|
140
|
-
description: "The response for the health request with errors.",
|
|
141
|
-
response: {
|
|
142
|
-
body: {
|
|
143
|
-
status: "error",
|
|
144
|
-
components: [
|
|
145
|
-
{
|
|
146
|
-
name: "Database",
|
|
147
|
-
status: "ok"
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
name: "Storage",
|
|
151
|
-
status: "error",
|
|
152
|
-
details: "The storage is full."
|
|
153
|
-
}
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
]
|
|
159
|
-
}
|
|
160
|
-
],
|
|
161
|
-
skipAuth: true
|
|
162
|
-
};
|
|
163
|
-
const specRoute = {
|
|
164
|
-
operationId: "serverSpec",
|
|
165
|
-
summary: "Get the OpenAPI specification for the endpoints",
|
|
166
|
-
tag: tagsInformation[0].name,
|
|
167
|
-
method: "GET",
|
|
168
|
-
path: `${baseRouteName}/spec`,
|
|
169
|
-
handler: async (httpRequestContext, request) => serverSpec(httpRequestContext, componentName),
|
|
170
|
-
responseType: [
|
|
171
|
-
{
|
|
172
|
-
type: "IServerSpecResponse",
|
|
173
|
-
examples: [
|
|
174
|
-
{
|
|
175
|
-
id: "specResponse",
|
|
176
|
-
description: "The response for the spec request.",
|
|
177
|
-
response: {
|
|
178
|
-
body: {
|
|
179
|
-
openapi: "3.1.0",
|
|
180
|
-
info: {},
|
|
181
|
-
paths: {}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
]
|
|
186
|
-
}
|
|
187
|
-
],
|
|
188
|
-
skipAuth: true
|
|
189
|
-
};
|
|
190
|
-
return [rootRoute, favIconRoute, informationRoute, healthRoute, specRoute];
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Get the root for the server.
|
|
194
|
-
* @param httpRequestContext The request context for the API.
|
|
195
|
-
* @param componentName The name of the component to use in the routes.
|
|
196
|
-
* @param request The request.
|
|
197
|
-
* @returns The response object with additional http response properties.
|
|
198
|
-
*/
|
|
199
|
-
async function serverRoot(httpRequestContext, componentName, request) {
|
|
200
|
-
const component = core.ComponentFactory.get(componentName);
|
|
201
|
-
return {
|
|
202
|
-
body: await component.root()
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Get the information for the server.
|
|
207
|
-
* @param httpRequestContext The request context for the API.
|
|
208
|
-
* @param componentName The name of the component to use in the routes.
|
|
209
|
-
* @param request The request.
|
|
210
|
-
* @returns The response object with additional http response properties.
|
|
211
|
-
*/
|
|
212
|
-
async function serverInfo(httpRequestContext, componentName, request) {
|
|
213
|
-
const component = core.ComponentFactory.get(componentName);
|
|
214
|
-
return {
|
|
215
|
-
body: await component.info()
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Get the health for the server.
|
|
220
|
-
* @param httpRequestContext The request context for the API.
|
|
221
|
-
* @param componentName The name of the component to use in the routes.
|
|
222
|
-
* @param request The request.
|
|
223
|
-
* @returns The response object with additional http response properties.
|
|
224
|
-
*/
|
|
225
|
-
async function serverHealth(httpRequestContext, componentName, request) {
|
|
226
|
-
const component = core.ComponentFactory.get(componentName);
|
|
227
|
-
return {
|
|
228
|
-
body: await component.health()
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Get the favicon for the server.
|
|
233
|
-
* @param httpRequestContext The request context for the API.
|
|
234
|
-
* @param componentName The name of the component to use in the routes.
|
|
235
|
-
* @param request The request.
|
|
236
|
-
* @returns The response object with additional http response properties.
|
|
237
|
-
*/
|
|
238
|
-
async function serverFavIcon(httpRequestContext, componentName, request) {
|
|
239
|
-
const component = core.ComponentFactory.get(componentName);
|
|
240
|
-
const favIcon = await component.favicon();
|
|
241
|
-
if (core.Is.uint8Array(favIcon)) {
|
|
242
|
-
return {
|
|
243
|
-
headers: {
|
|
244
|
-
[web.HeaderTypes.ContentType]: "image/x-icon"
|
|
245
|
-
},
|
|
246
|
-
body: favIcon
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
return {
|
|
250
|
-
statusCode: web.HttpStatusCode.notFound
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Get the spec for the server.
|
|
255
|
-
* @param httpRequestContext The request context for the API.
|
|
256
|
-
* @param componentName The name of the component to use in the routes.
|
|
257
|
-
* @param request The request.
|
|
258
|
-
* @returns The response object with additional http response properties.
|
|
259
|
-
*/
|
|
260
|
-
async function serverSpec(httpRequestContext, componentName, request) {
|
|
261
|
-
const component = core.ComponentFactory.get(componentName);
|
|
262
|
-
const spec = await component.spec();
|
|
263
|
-
if (core.Is.objectValue(spec)) {
|
|
264
|
-
return {
|
|
265
|
-
body: spec
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
return {
|
|
269
|
-
statusCode: web.HttpStatusCode.notFound
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Copyright 2024 IOTA Stiftung.
|
|
274
|
-
// SPDX-License-Identifier: Apache-2.0.
|
|
275
|
-
/**
|
|
276
|
-
* The information service for the server.
|
|
277
|
-
*/
|
|
278
|
-
class InformationService {
|
|
279
|
-
/**
|
|
280
|
-
* Runtime name for the class.
|
|
281
|
-
*/
|
|
282
|
-
CLASS_NAME = "InformationService";
|
|
283
|
-
/**
|
|
284
|
-
* The server information.
|
|
285
|
-
* @internal
|
|
286
|
-
*/
|
|
287
|
-
_serverInfo;
|
|
288
|
-
/**
|
|
289
|
-
* The server health.
|
|
290
|
-
* @internal
|
|
291
|
-
*/
|
|
292
|
-
_healthInfo;
|
|
293
|
-
/**
|
|
294
|
-
* The path to the favicon Spec.
|
|
295
|
-
* @internal
|
|
296
|
-
*/
|
|
297
|
-
_faviconPath;
|
|
298
|
-
/**
|
|
299
|
-
* The favicon.
|
|
300
|
-
* @internal
|
|
301
|
-
*/
|
|
302
|
-
_favicon;
|
|
303
|
-
/**
|
|
304
|
-
* The path to the OpenAPI Spec.
|
|
305
|
-
* @internal
|
|
306
|
-
*/
|
|
307
|
-
_openApiSpecPath;
|
|
308
|
-
/**
|
|
309
|
-
* The OpenAPI spec.
|
|
310
|
-
* @internal
|
|
311
|
-
*/
|
|
312
|
-
_openApiSpec;
|
|
313
|
-
/**
|
|
314
|
-
* Create a new instance of InformationService.
|
|
315
|
-
* @param options The options to create the service.
|
|
316
|
-
*/
|
|
317
|
-
constructor(options) {
|
|
318
|
-
core.Guards.object(this.CLASS_NAME, "options", options);
|
|
319
|
-
core.Guards.object(this.CLASS_NAME, "options.config", options.config);
|
|
320
|
-
core.Guards.object(this.CLASS_NAME, "options.config.serverInfo", options.config.serverInfo);
|
|
321
|
-
this._serverInfo = options.config.serverInfo;
|
|
322
|
-
this._healthInfo = {
|
|
323
|
-
status: "ok"
|
|
324
|
-
};
|
|
325
|
-
this._faviconPath = options.config.favIconPath;
|
|
326
|
-
this._openApiSpecPath = options.config.openApiSpecPath;
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* The service needs to be started when the application is initialized.
|
|
330
|
-
* @returns Nothing.
|
|
331
|
-
*/
|
|
332
|
-
async start() {
|
|
333
|
-
const openApiPath = this._openApiSpecPath;
|
|
334
|
-
if (core.Is.stringValue(openApiPath)) {
|
|
335
|
-
const contentBuffer = await promises.readFile(openApiPath, "utf8");
|
|
336
|
-
this._openApiSpec = JSON.parse(contentBuffer);
|
|
337
|
-
}
|
|
338
|
-
const favIconPath = this._faviconPath;
|
|
339
|
-
if (core.Is.stringValue(favIconPath)) {
|
|
340
|
-
this._favicon = await promises.readFile(favIconPath);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Get the root information.
|
|
345
|
-
* @returns The root information.
|
|
346
|
-
*/
|
|
347
|
-
async root() {
|
|
348
|
-
return `${this._serverInfo.name} - ${this._serverInfo.version}`;
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Get the server information.
|
|
352
|
-
* @returns The service information.
|
|
353
|
-
*/
|
|
354
|
-
async info() {
|
|
355
|
-
return this._serverInfo;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Get the favicon.
|
|
359
|
-
* @returns The favicon.
|
|
360
|
-
*/
|
|
361
|
-
async favicon() {
|
|
362
|
-
return this._favicon;
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Get the OpenAPI spec.
|
|
366
|
-
* @returns The OpenAPI spec.
|
|
367
|
-
*/
|
|
368
|
-
async spec() {
|
|
369
|
-
return this._openApiSpec;
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Get the server health.
|
|
373
|
-
* @returns The service health.
|
|
374
|
-
*/
|
|
375
|
-
async health() {
|
|
376
|
-
let errorCount = 0;
|
|
377
|
-
let warningCount = 0;
|
|
378
|
-
if (core.Is.arrayValue(this._healthInfo.components)) {
|
|
379
|
-
errorCount = this._healthInfo.components.filter(c => c.status === "error").length;
|
|
380
|
-
warningCount = this._healthInfo.components.filter(c => c.status === "warning").length;
|
|
381
|
-
}
|
|
382
|
-
if (errorCount > 0) {
|
|
383
|
-
this._healthInfo.status = "error";
|
|
384
|
-
}
|
|
385
|
-
else if (warningCount > 0) {
|
|
386
|
-
this._healthInfo.status = "warning";
|
|
387
|
-
}
|
|
388
|
-
else {
|
|
389
|
-
this._healthInfo.status = "ok";
|
|
390
|
-
}
|
|
391
|
-
return this._healthInfo;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Set the status of a component.
|
|
395
|
-
* @param name The component name.
|
|
396
|
-
* @param status The status of the component.
|
|
397
|
-
* @param details The details for the status.
|
|
398
|
-
* @returns Nothing.
|
|
399
|
-
*/
|
|
400
|
-
async setComponentHealth(name, status, details) {
|
|
401
|
-
const component = this._healthInfo.components?.find(c => c.name === name);
|
|
402
|
-
if (core.Is.undefined(component)) {
|
|
403
|
-
this._healthInfo.components ??= [];
|
|
404
|
-
this._healthInfo.components.push({
|
|
405
|
-
name,
|
|
406
|
-
status,
|
|
407
|
-
details
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
component.status = status;
|
|
412
|
-
component.details = details;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Remove the status of a component.
|
|
417
|
-
* @param name The component name.
|
|
418
|
-
* @returns Nothing.
|
|
419
|
-
*/
|
|
420
|
-
async removeComponentHealth(name) {
|
|
421
|
-
if (core.Is.arrayValue(this._healthInfo.components)) {
|
|
422
|
-
const componentIndex = this._healthInfo.components.findIndex(c => c.name === name);
|
|
423
|
-
if (componentIndex !== -1) {
|
|
424
|
-
this._healthInfo.components.splice(componentIndex, 1);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
const restEntryPoints = [
|
|
431
|
-
{
|
|
432
|
-
name: "information",
|
|
433
|
-
defaultBaseRoute: "",
|
|
434
|
-
tags: tagsInformation,
|
|
435
|
-
generateRoutes: generateRestRoutesInformation
|
|
436
|
-
}
|
|
437
|
-
];
|
|
438
|
-
|
|
439
|
-
exports.InformationService = InformationService;
|
|
440
|
-
exports.generateRestRoutesInformation = generateRestRoutesInformation;
|
|
441
|
-
exports.restEntryPoints = restEntryPoints;
|
|
442
|
-
exports.serverFavIcon = serverFavIcon;
|
|
443
|
-
exports.serverHealth = serverHealth;
|
|
444
|
-
exports.serverInfo = serverInfo;
|
|
445
|
-
exports.serverRoot = serverRoot;
|
|
446
|
-
exports.serverSpec = serverSpec;
|
|
447
|
-
exports.tagsInformation = tagsInformation;
|