@futdevpro/nts-dynamo 1.15.8 → 1.15.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/.cursor/rules/_ag_frontend-structure.mdc +5 -5
- package/__documentations/nts-integration-tests-2026-03-17.md +26 -0
- package/build/_collections/default-fallback-cache-max-age.const.d.ts +3 -0
- package/build/_collections/default-fallback-cache-max-age.const.d.ts.map +1 -0
- package/build/_collections/default-fallback-cache-max-age.const.js +6 -0
- package/build/_collections/default-fallback-cache-max-age.const.js.map +1 -0
- package/build/_collections/default-not-found-page.const.d.ts +6 -0
- package/build/_collections/default-not-found-page.const.d.ts.map +1 -0
- package/build/_collections/default-not-found-page.const.js +25 -0
- package/build/_collections/default-not-found-page.const.js.map +1 -0
- package/build/_collections/default-socket-path.const.d.ts +3 -0
- package/build/_collections/default-socket-path.const.d.ts.map +1 -0
- package/build/_collections/default-socket-path.const.js +6 -0
- package/build/_collections/default-socket-path.const.js.map +1 -0
- package/build/_models/control-models/http-settings.control-model.d.ts +7 -0
- package/build/_models/control-models/http-settings.control-model.d.ts.map +1 -1
- package/build/_models/control-models/http-settings.control-model.js +7 -0
- package/build/_models/control-models/http-settings.control-model.js.map +1 -1
- package/build/_models/interfaces/static-client-settings.interface.d.ts +29 -0
- package/build/_models/interfaces/static-client-settings.interface.d.ts.map +1 -0
- package/build/_models/interfaces/static-client-settings.interface.js +3 -0
- package/build/_models/interfaces/static-client-settings.interface.js.map +1 -0
- package/build/_modules/mock/app-extended-server.mock.js +2 -2
- package/build/_modules/mock/app-extended-server.mock.js.map +1 -1
- package/build/_modules/mock/app-integration-test.mock.d.ts +20 -0
- package/build/_modules/mock/app-integration-test.mock.d.ts.map +1 -0
- package/build/_modules/mock/app-integration-test.mock.js +46 -0
- package/build/_modules/mock/app-integration-test.mock.js.map +1 -0
- package/build/_modules/mock/app-server.mock.js +2 -2
- package/build/_modules/mock/app-server.mock.js.map +1 -1
- package/build/_modules/mock/socket-client.mock.js +1 -1
- package/build/_modules/mock/socket-client.mock.js.map +1 -1
- package/build/_modules/mock/socket-server.mock.d.ts +1 -1
- package/build/_modules/mock/socket-server.mock.d.ts.map +1 -1
- package/build/_modules/mock/socket-server.mock.js +2 -8
- package/build/_modules/mock/socket-server.mock.js.map +1 -1
- package/build/_modules/server/errors/errors.data-service.d.ts.map +1 -1
- package/build/_modules/server/errors/errors.data-service.js +20 -9
- package/build/_modules/server/errors/errors.data-service.js.map +1 -1
- package/build/_modules/socket/_services/socket-server.service.d.ts.map +1 -1
- package/build/_modules/socket/_services/socket-server.service.js +3 -1
- package/build/_modules/socket/_services/socket-server.service.js.map +1 -1
- package/build/_modules/socket/app-extended.server.d.ts +1 -0
- package/build/_modules/socket/app-extended.server.d.ts.map +1 -1
- package/build/_modules/socket/app-extended.server.js +6 -2
- package/build/_modules/socket/app-extended.server.js.map +1 -1
- package/build/_services/base/data.service.d.ts.map +1 -1
- package/build/_services/base/data.service.js +4 -5
- package/build/_services/base/data.service.js.map +1 -1
- package/build/_services/base/db.service.d.ts.map +1 -1
- package/build/_services/base/db.service.js +8 -0
- package/build/_services/base/db.service.js.map +1 -1
- package/build/_services/server/app.server.d.ts +18 -0
- package/build/_services/server/app.server.d.ts.map +1 -1
- package/build/_services/server/app.server.js +74 -2
- package/build/_services/server/app.server.js.map +1 -1
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/nodemon.json +2 -1
- package/package.json +4 -4
- package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -0
- package/src/_collections/default-fallback-cache-max-age.const.ts +2 -0
- package/src/_collections/default-not-found-page.const.spec.ts +19 -0
- package/src/_collections/default-not-found-page.const.ts +22 -0
- package/src/_collections/default-socket-path.const.spec.ts +12 -0
- package/src/_collections/default-socket-path.const.ts +2 -0
- package/src/_models/control-models/http-settings.control-model.spec.ts +11 -0
- package/src/_models/control-models/http-settings.control-model.ts +8 -0
- package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -0
- package/src/_models/interfaces/static-client-settings.interface.ts +28 -0
- package/src/_modules/mock/app-extended-server.mock.ts +2 -2
- package/src/_modules/mock/app-integration-test.mock.ts +51 -0
- package/src/_modules/mock/app-server.mock.ts +2 -2
- package/src/_modules/mock/socket-client.mock.spec.ts +1 -1
- package/src/_modules/mock/socket-client.mock.ts +1 -1
- package/src/_modules/mock/socket-server.mock.spec.ts +1 -1
- package/src/_modules/mock/socket-server.mock.ts +5 -13
- package/src/_modules/server/errors/errors.data-service.spec.ts +6 -6
- package/src/_modules/server/errors/errors.data-service.ts +24 -9
- package/src/_modules/socket/_services/socket-server.service.ts +6 -2
- package/src/_modules/socket/app-extended.integration.spec.ts +85 -0
- package/src/_modules/socket/app-extended.server.ts +6 -2
- package/src/_services/base/data.service.ts +4 -7
- package/src/_services/base/db.service.ts +11 -3
- package/src/_services/route/routing-module.service.spec.ts +15 -0
- package/src/_services/server/app.server.ts +107 -2
- package/src/index.ts +4 -0
|
@@ -1495,11 +1495,17 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
|
|
|
1495
1495
|
}
|
|
1496
1496
|
|
|
1497
1497
|
if (!properties._deletedBy) {
|
|
1498
|
-
properties._deletedBy = {
|
|
1498
|
+
properties._deletedBy = {
|
|
1499
1499
|
key: '_deletedBy', type: DyFM_BasicProperty_Type.string,
|
|
1500
1500
|
};
|
|
1501
1501
|
}
|
|
1502
1502
|
|
|
1503
|
+
if (!properties._archived) {
|
|
1504
|
+
properties._archived = {
|
|
1505
|
+
key: '_archived', type: DyFM_BasicProperty_Type.date,
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1503
1509
|
return properties;
|
|
1504
1510
|
}
|
|
1505
1511
|
|
|
@@ -1521,10 +1527,12 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
|
|
|
1521
1527
|
}
|
|
1522
1528
|
|
|
1523
1529
|
if (!properties._archived) {
|
|
1524
|
-
properties._archived = {
|
|
1530
|
+
properties._archived = {
|
|
1525
1531
|
key: '_archived', type: DyFM_BasicProperty_Type.date,
|
|
1526
|
-
required: true,
|
|
1532
|
+
required: true,
|
|
1527
1533
|
};
|
|
1534
|
+
} else if (properties._archived.required === undefined) {
|
|
1535
|
+
properties._archived.required = true;
|
|
1528
1536
|
}
|
|
1529
1537
|
|
|
1530
1538
|
return properties;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { DyFM_Error, DyFM_HttpCallType } from '@futdevpro/fsm-dynamo';
|
|
3
3
|
|
|
4
|
+
import { DyNTS_global_settings } from '../../_collections/global-settings.const';
|
|
4
5
|
import { DyNTS_RouteSecurity } from '../../_enums/route-security.enum';
|
|
5
6
|
import { DyNTS_Endpoint_Params } from '../../_models/control-models/endpoint-params.control-model';
|
|
6
7
|
import {
|
|
@@ -80,4 +81,18 @@ describe('| DyNTS_RoutingModule', () => {
|
|
|
80
81
|
routingModule.endpoints = [ mockEndpoint, mockEndpoint ];
|
|
81
82
|
expect(() => routingModule['mountRoutes']()).toThrowError(/ENDPOINT DUPLICATION/);
|
|
82
83
|
});
|
|
84
|
+
|
|
85
|
+
it('| should use DyNTS_global_settings.baseUrl as route prefix', () => {
|
|
86
|
+
const originalBaseUrl: string = DyNTS_global_settings.baseUrl;
|
|
87
|
+
try {
|
|
88
|
+
DyNTS_global_settings.baseUrl = '/custom-api';
|
|
89
|
+
const moduleWithCustomBase: DyNTS_RoutingModule = new DyNTS_RoutingModule({
|
|
90
|
+
route: '/foo',
|
|
91
|
+
controllers: [ mockController ],
|
|
92
|
+
});
|
|
93
|
+
expect(moduleWithCustomBase.route).toBe('/custom-api/foo');
|
|
94
|
+
} finally {
|
|
95
|
+
DyNTS_global_settings.baseUrl = originalBaseUrl;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
83
98
|
});
|
|
@@ -8,6 +8,7 @@ import * as BodyParser from 'body-parser';
|
|
|
8
8
|
import * as FileSystem from 'fs';
|
|
9
9
|
import * as Http from 'http';
|
|
10
10
|
import * as Https from 'https';
|
|
11
|
+
import * as Path from 'path';
|
|
11
12
|
import * as dotenv from 'dotenv'
|
|
12
13
|
|
|
13
14
|
/* import { version } from '../../../package.json'; */
|
|
@@ -25,6 +26,8 @@ import {
|
|
|
25
26
|
second
|
|
26
27
|
} from '@futdevpro/fsm-dynamo';
|
|
27
28
|
|
|
29
|
+
import { DyNTS_defaultFallbackCacheMaxAge } from '../../_collections/default-fallback-cache-max-age.const';
|
|
30
|
+
import { DyNTS_defaultNotFoundPageHtml } from '../../_collections/default-not-found-page.const';
|
|
28
31
|
import { DyNTS_global_settings } from '../../_collections/global-settings.const';
|
|
29
32
|
import { DyNTS_RouteSecurity } from '../../_enums/route-security.enum';
|
|
30
33
|
import { DyNTS_App_Params } from '../../_models/control-models/app-params.control-model';
|
|
@@ -41,6 +44,9 @@ import {
|
|
|
41
44
|
import {
|
|
42
45
|
DyNTS_GlobalService_Settings
|
|
43
46
|
} from '../../_models/interfaces/global-service-settings.interface';
|
|
47
|
+
import {
|
|
48
|
+
DyNTS_StaticClient_Settings
|
|
49
|
+
} from '../../_models/interfaces/static-client-settings.interface';
|
|
44
50
|
import { DyNTS_SingletonService } from '../base/singleton.service';
|
|
45
51
|
import { DyNTS_GlobalService } from '../core/global.service';
|
|
46
52
|
import { DyNTS_RoutingModule } from '../route/routing-module.service';
|
|
@@ -457,6 +463,10 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
457
463
|
this._cert = this.getCertificationSettings();
|
|
458
464
|
}
|
|
459
465
|
|
|
466
|
+
if (this.getApiBasePath) {
|
|
467
|
+
DyNTS_global_settings.baseUrl = this.getApiBasePath();
|
|
468
|
+
}
|
|
469
|
+
|
|
460
470
|
if (this.getRoutingModules) {
|
|
461
471
|
this._routingModules = this.getRoutingModules();
|
|
462
472
|
|
|
@@ -499,6 +509,8 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
499
509
|
await this.mountSecureRoutes();
|
|
500
510
|
}
|
|
501
511
|
|
|
512
|
+
await this.mountStaticClient();
|
|
513
|
+
|
|
502
514
|
if (this.logSetup) {
|
|
503
515
|
DyFM_Log.log(`\nRoutes mounted.... server using security: ${this._security}`);
|
|
504
516
|
}
|
|
@@ -951,7 +963,7 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
951
963
|
|
|
952
964
|
try {
|
|
953
965
|
if (this._security && this._security !== DyNTS_RouteSecurity.secure) {
|
|
954
|
-
if (
|
|
966
|
+
if (this._portSettings.httpPort === undefined || this._portSettings.httpPort === null) {
|
|
955
967
|
let errorMsg: string =
|
|
956
968
|
`\nYou have open routes, but httpPort is not set!` +
|
|
957
969
|
`\nThere are ${this._routingModules.filter(
|
|
@@ -1151,9 +1163,19 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
1151
1163
|
this.params.expressBacklog,
|
|
1152
1164
|
(): void => {
|
|
1153
1165
|
this.systemControls.httpServer.started = true;
|
|
1166
|
+
|
|
1167
|
+
const resolvedPort: number = this.httpServer?.address?.()?.['port'] ?? this._portSettings.httpPort;
|
|
1168
|
+
|
|
1169
|
+
if (this._portSettings.httpPort === 0) {
|
|
1170
|
+
DyFM_Log.H_warn(
|
|
1171
|
+
`\nHTTP (open) server is using a randomly selected port by the OS: ${resolvedPort}` +
|
|
1172
|
+
`\n (httpPort was set to 0 — this is intended for testing only)`
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1154
1176
|
DyFM_Log.success(
|
|
1155
1177
|
`\nHTTP (open) server is listening on port: ` +
|
|
1156
|
-
`${this.params.openHost}:${
|
|
1178
|
+
`${this.params.openHost}:${resolvedPort}`
|
|
1157
1179
|
);
|
|
1158
1180
|
|
|
1159
1181
|
resolve();
|
|
@@ -1374,6 +1396,77 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
1374
1396
|
}
|
|
1375
1397
|
}
|
|
1376
1398
|
|
|
1399
|
+
/**
|
|
1400
|
+
* Ha getStaticClientSettings() visszaad beállításokat, a client static fájlok a '/' alatt
|
|
1401
|
+
* lesznek kiszolgálva (API route-ok után). SPA fallback opcionális (fallbackPath).
|
|
1402
|
+
* Asset cache (assetCacheMaxAge, assetCacheImmutable) és fallback cache (fallbackCacheMaxAge)
|
|
1403
|
+
* opcionálisak; ha nincs megadva fallbackCacheMaxAge, DyNTS_defaultFallbackCacheMaxAge (0) marad.
|
|
1404
|
+
*/
|
|
1405
|
+
private async mountStaticClient(): Promise<void> {
|
|
1406
|
+
const settings: DyNTS_StaticClient_Settings | undefined = this.getStaticClientSettings?.();
|
|
1407
|
+
if (!settings) {
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
const absoluteRoot: string = Path.isAbsolute(settings.root)
|
|
1412
|
+
? settings.root
|
|
1413
|
+
: Path.resolve(process.cwd(), settings.root);
|
|
1414
|
+
|
|
1415
|
+
const hasAssetCache: boolean =
|
|
1416
|
+
settings.assetCacheMaxAge !== undefined || settings.assetCacheImmutable === true;
|
|
1417
|
+
const staticOptions: { setHeaders: (res: Express.Response) => void } | undefined =
|
|
1418
|
+
hasAssetCache && settings.assetCacheMaxAge !== undefined
|
|
1419
|
+
? {
|
|
1420
|
+
setHeaders: (res: Express.Response): void => {
|
|
1421
|
+
const maxAge: number = settings.assetCacheMaxAge!;
|
|
1422
|
+
const immutable: string =
|
|
1423
|
+
settings.assetCacheImmutable === true ? ', immutable' : '';
|
|
1424
|
+
res.setHeader('Cache-Control', `max-age=${maxAge}${immutable}`);
|
|
1425
|
+
},
|
|
1426
|
+
}
|
|
1427
|
+
: undefined;
|
|
1428
|
+
|
|
1429
|
+
const staticMiddleware: Express.Handler =
|
|
1430
|
+
staticOptions
|
|
1431
|
+
? Express.static(absoluteRoot, staticOptions)
|
|
1432
|
+
: Express.static(absoluteRoot);
|
|
1433
|
+
|
|
1434
|
+
const fallbackMaxAge: number =
|
|
1435
|
+
settings.fallbackCacheMaxAge ?? DyNTS_defaultFallbackCacheMaxAge;
|
|
1436
|
+
|
|
1437
|
+
if (this.openExpress) {
|
|
1438
|
+
this.openExpress.use('/', staticMiddleware);
|
|
1439
|
+
if (settings.fallbackPath) {
|
|
1440
|
+
this.openExpress.get('*', (req: Express.Request, res: Express.Response): void => {
|
|
1441
|
+
res.setHeader('Cache-Control', `max-age=${fallbackMaxAge}`);
|
|
1442
|
+
res.sendFile(settings.fallbackPath!, { root: absoluteRoot });
|
|
1443
|
+
});
|
|
1444
|
+
} else {
|
|
1445
|
+
this.openExpress.get('*', (req: Express.Request, res: Express.Response): void => {
|
|
1446
|
+
res.status(404).type('html').send(DyNTS_defaultNotFoundPageHtml);
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
if (this.secureExpress) {
|
|
1452
|
+
this.secureExpress.use('/', staticMiddleware);
|
|
1453
|
+
if (settings.fallbackPath) {
|
|
1454
|
+
this.secureExpress.get('*', (req: Express.Request, res: Express.Response): void => {
|
|
1455
|
+
res.setHeader('Cache-Control', `max-age=${fallbackMaxAge}`);
|
|
1456
|
+
res.sendFile(settings.fallbackPath!, { root: absoluteRoot });
|
|
1457
|
+
});
|
|
1458
|
+
} else {
|
|
1459
|
+
this.secureExpress.get('*', (req: Express.Request, res: Express.Response): void => {
|
|
1460
|
+
res.status(404).type('html').send(DyNTS_defaultNotFoundPageHtml);
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
if (this.logSetup) {
|
|
1466
|
+
DyFM_Log.log(`\nStatic client mounted at / (root: ${absoluteRoot})`);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1377
1470
|
/**
|
|
1378
1471
|
*
|
|
1379
1472
|
*/
|
|
@@ -1444,6 +1537,12 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
1444
1537
|
*/
|
|
1445
1538
|
overrideDynamoNTSGlobalSettings?(): void;
|
|
1446
1539
|
|
|
1540
|
+
/**
|
|
1541
|
+
* Ha megadva, a visszaadott értéket használjuk a route prefix-ként
|
|
1542
|
+
* (DyNTS_global_settings.baseUrl felülírása erre az app-ra).
|
|
1543
|
+
*/
|
|
1544
|
+
getApiBasePath?(): string;
|
|
1545
|
+
|
|
1447
1546
|
/**
|
|
1448
1547
|
* MISSING Description (TODO)
|
|
1449
1548
|
*/
|
|
@@ -1459,6 +1558,12 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
|
|
|
1459
1558
|
*/
|
|
1460
1559
|
getCertificationSettings?(): DyNTS_Certification_Settings;
|
|
1461
1560
|
|
|
1561
|
+
/**
|
|
1562
|
+
* Ha megadva, a client static fájlok a '/' alatt lesznek kiszolgálva (API route-ok után).
|
|
1563
|
+
* Opcionális fallbackPath pl. SPA index.html-hez.
|
|
1564
|
+
*/
|
|
1565
|
+
getStaticClientSettings?(): DyNTS_StaticClient_Settings | undefined;
|
|
1566
|
+
|
|
1462
1567
|
/**
|
|
1463
1568
|
* MISSING Description (TODO)
|
|
1464
1569
|
*/
|
package/src/index.ts
CHANGED
|
@@ -27,6 +27,9 @@ try {
|
|
|
27
27
|
// COLLECTIONS
|
|
28
28
|
export * from './_collections/archive.util';
|
|
29
29
|
export * from './_collections/atlas-default-db-options.const';
|
|
30
|
+
export * from './_collections/default-fallback-cache-max-age.const';
|
|
31
|
+
export * from './_collections/default-not-found-page.const';
|
|
32
|
+
export * from './_collections/default-socket-path.const';
|
|
30
33
|
export * from './_collections/get-environment-settings.util';
|
|
31
34
|
export * from './_collections/global-settings.const';
|
|
32
35
|
|
|
@@ -46,6 +49,7 @@ export * from './_models/interfaces/environment-settings.interface';
|
|
|
46
49
|
export * from './_models/interfaces/global-service-settings.interface';
|
|
47
50
|
export * from './_models/interfaces/global-settings.interface';
|
|
48
51
|
export * from './_models/interfaces/routing-module-settings.interface';
|
|
52
|
+
export * from './_models/interfaces/static-client-settings.interface';
|
|
49
53
|
|
|
50
54
|
// models/CONTROL MODELS
|
|
51
55
|
export * from './_models/control-models/api-call-params.control-model';
|