taon 21.0.52 → 21.0.53
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/bin/taon +5 -5
- package/bin/taon-debug +5 -5
- package/bin/taon-debug-brk +4 -4
- package/browser/package.json +1 -1
- package/browser-prod/package.json +1 -1
- package/icon-menu-taon.svg +15 -15
- package/lib/build-info._auto-generated_.d.ts +1 -1
- package/lib/build-info._auto-generated_.js +1 -1
- package/lib/package.json +1 -1
- package/lib/ui/index.js +2 -2
- package/lib/ui/taon-admin-mode-configuration/index.js +2 -2
- package/lib-prod/base-classes/base-abstract-entity.js +33 -0
- package/lib-prod/base-classes/base-angular-service.js +56 -0
- package/lib-prod/base-classes/base-class.js +37 -0
- package/lib-prod/base-classes/base-context.js +21 -0
- package/lib-prod/base-classes/base-controller.js +162 -0
- package/lib-prod/base-classes/base-crud-controller.js +235 -0
- package/lib-prod/base-classes/base-custom-repository.js +20 -0
- package/lib-prod/base-classes/base-electron-service.js +0 -0
- package/lib-prod/base-classes/base-entity.js +32 -0
- package/lib-prod/base-classes/base-file-upload.middleware.js +78 -0
- package/lib-prod/base-classes/base-injector.js +202 -0
- package/lib-prod/base-classes/base-middleware.js +6 -0
- package/lib-prod/base-classes/base-migration.js +23 -0
- package/lib-prod/base-classes/base-provider.js +6 -0
- package/lib-prod/base-classes/base-repository.js +589 -0
- package/lib-prod/base-classes/base-subscriber-for-entity.js +154 -0
- package/lib-prod/base-classes/base.js +0 -0
- package/lib-prod/build-info._auto-generated_.js +14 -0
- package/lib-prod/config/controller-config.js +28 -0
- package/lib-prod/config/controller-options.js +6 -0
- package/lib-prod/config/method-config.js +9 -0
- package/lib-prod/config/param-config.js +9 -0
- package/lib-prod/constants.js +29 -0
- package/lib-prod/context-db-migrations.js +339 -0
- package/lib-prod/create-context.js +152 -0
- package/lib-prod/decorators/classes/controller-decorator.js +21 -0
- package/lib-prod/decorators/classes/entity-decorator.js +49 -0
- package/lib-prod/decorators/classes/middleware-decorator.js +26 -0
- package/lib-prod/decorators/classes/migration-decorator.js +24 -0
- package/lib-prod/decorators/classes/provider-decorator.js +25 -0
- package/lib-prod/decorators/classes/repository-decorator.js +24 -0
- package/lib-prod/decorators/classes/subscriber-decorator.js +25 -0
- package/lib-prod/decorators/decorator-abstract-opt.js +5 -0
- package/lib-prod/decorators/http/http-decorators.js +5 -0
- package/lib-prod/decorators/http/http-methods-decorators.js +144 -0
- package/lib-prod/decorators/http/http-params-decorators.js +68 -0
- package/lib-prod/dependency-injection/di-container.js +31 -0
- package/lib-prod/endpoint-context-storage.js +36 -0
- package/lib-prod/endpoint-context.js +2033 -0
- package/lib-prod/entity-process.js +214 -0
- package/lib-prod/env/env.angular-node-app.js +130 -0
- package/lib-prod/env/env.docs-webapp.js +130 -0
- package/lib-prod/env/env.electron-app.js +130 -0
- package/lib-prod/env/env.mobile-app.js +130 -0
- package/lib-prod/env/env.npm-lib-and-cli-tool.js +130 -0
- package/lib-prod/env/env.vscode-plugin.js +130 -0
- package/lib-prod/env/index.js +6 -0
- package/lib-prod/express-types.js +0 -0
- package/lib-prod/formly/formly.models.js +0 -0
- package/lib-prod/formly/fromly.js +184 -0
- package/lib-prod/formly/type-from-entity.js +58 -0
- package/lib-prod/get-response-value.js +19 -0
- package/lib-prod/global-state/taon-global-state/index.js +5 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.abstract.context.js +20 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.constants.js +10 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.controller.js +48 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.entity.js +48 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.middleware.js +22 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.models.js +34 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.provider.js +22 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.repository.js +47 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.subscriber.js +29 -0
- package/lib-prod/global-state/taon-global-state/taon-global-state.utils.js +11 -0
- package/lib-prod/global-state/taon-transaction-registry/index.js +10 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.abstract.context.js +22 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.constants.js +8 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.controller.js +41 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.entity.js +56 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.middleware.js +22 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.models.js +10 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.provider.js +22 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.repository.js +36 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.subscriber.js +29 -0
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.utils.js +6 -0
- package/lib-prod/helpers/class-helpers.js +195 -0
- package/lib-prod/helpers/clone-obj.js +21 -0
- package/lib-prod/helpers/taon-helpers.js +129 -0
- package/lib-prod/index._auto-generated_.js +0 -0
- package/lib-prod/index.js +231 -0
- package/lib-prod/inject.js +34 -0
- package/lib-prod/migrations/index.js +1 -0
- package/lib-prod/migrations/migrations_index._auto-generated_.js +0 -0
- package/lib-prod/models.js +109 -0
- package/lib-prod/orm/columns.js +124 -0
- package/lib-prod/orm/index.js +1 -0
- package/lib-prod/package.json +1 -1
- package/lib-prod/realtime/realtime-client.js +196 -0
- package/lib-prod/realtime/realtime-core.js +82 -0
- package/lib-prod/realtime/realtime-server.js +252 -0
- package/lib-prod/realtime/realtime-strategy/index.js +4 -0
- package/lib-prod/realtime/realtime-strategy/realtime-strategy-ipc.js +226 -0
- package/lib-prod/realtime/realtime-strategy/realtime-strategy-mock.js +262 -0
- package/lib-prod/realtime/realtime-strategy/realtime-strategy-socket-io.js +21 -0
- package/lib-prod/realtime/realtime-strategy/realtime-strategy.js +14 -0
- package/lib-prod/realtime/realtime-subs-manager.js +96 -0
- package/lib-prod/realtime/realtime.models.js +0 -0
- package/lib-prod/symbols.js +109 -0
- package/lib-prod/ui/index.js +5 -0
- package/lib-prod/ui/taon-admin-mode-configuration/index.js +5 -0
- package/lib-prod/validators.js +74 -0
- package/package.json +1 -1
- package/websql/package.json +1 -1
- package/websql-prod/package.json +1 -1
- package/lib-prod/base-classes/base-abstract-entity.ts +0 -34
- package/lib-prod/base-classes/base-angular-service.ts +0 -107
- package/lib-prod/base-classes/base-class.ts +0 -46
- package/lib-prod/base-classes/base-context.ts +0 -21
- package/lib-prod/base-classes/base-controller.ts +0 -240
- package/lib-prod/base-classes/base-crud-controller.ts +0 -298
- package/lib-prod/base-classes/base-custom-repository.ts +0 -10
- package/lib-prod/base-classes/base-electron-service.ts +0 -60
- package/lib-prod/base-classes/base-entity.ts +0 -28
- package/lib-prod/base-classes/base-file-upload.middleware.ts +0 -92
- package/lib-prod/base-classes/base-injector.ts +0 -278
- package/lib-prod/base-classes/base-middleware.ts +0 -71
- package/lib-prod/base-classes/base-migration.ts +0 -26
- package/lib-prod/base-classes/base-provider.ts +0 -8
- package/lib-prod/base-classes/base-repository.ts +0 -942
- package/lib-prod/base-classes/base-subscriber-for-entity.ts +0 -196
- package/lib-prod/base-classes/base.ts +0 -31
- package/lib-prod/build-info._auto-generated_.ts +0 -27
- package/lib-prod/config/controller-config.ts +0 -58
- package/lib-prod/config/controller-options.ts +0 -19
- package/lib-prod/config/method-config.ts +0 -55
- package/lib-prod/config/param-config.ts +0 -16
- package/lib-prod/constants.ts +0 -63
- package/lib-prod/context-db-migrations.ts +0 -488
- package/lib-prod/create-context.ts +0 -345
- package/lib-prod/decorators/classes/controller-decorator.ts +0 -25
- package/lib-prod/decorators/classes/entity-decorator.ts +0 -57
- package/lib-prod/decorators/classes/middleware-decorator.ts +0 -29
- package/lib-prod/decorators/classes/migration-decorator.ts +0 -27
- package/lib-prod/decorators/classes/provider-decorator.ts +0 -28
- package/lib-prod/decorators/classes/repository-decorator.ts +0 -26
- package/lib-prod/decorators/classes/subscriber-decorator.ts +0 -28
- package/lib-prod/decorators/decorator-abstract-opt.ts +0 -4
- package/lib-prod/decorators/http/http-decorators.ts +0 -26
- package/lib-prod/decorators/http/http-methods-decorators.ts +0 -275
- package/lib-prod/decorators/http/http-params-decorators.ts +0 -105
- package/lib-prod/dependency-injection/di-container.ts +0 -39
- package/lib-prod/endpoint-context-storage.ts +0 -47
- package/lib-prod/endpoint-context.ts +0 -3110
- package/lib-prod/entity-process.ts +0 -286
- package/lib-prod/env/env.angular-node-app.ts +0 -66
- package/lib-prod/env/env.docs-webapp.ts +0 -66
- package/lib-prod/env/env.electron-app.ts +0 -66
- package/lib-prod/env/env.mobile-app.ts +0 -66
- package/lib-prod/env/env.npm-lib-and-cli-tool.ts +0 -66
- package/lib-prod/env/env.vscode-plugin.ts +0 -66
- package/lib-prod/env/index.ts +0 -6
- package/lib-prod/express-types.ts +0 -4
- package/lib-prod/formly/formly.models.ts +0 -7
- package/lib-prod/formly/fromly.ts +0 -261
- package/lib-prod/formly/type-from-entity.ts +0 -80
- package/lib-prod/get-response-value.ts +0 -30
- package/lib-prod/global-state/taon-global-state/index.ts +0 -6
- package/lib-prod/global-state/taon-global-state/taon-global-state.abstract.context.ts +0 -21
- package/lib-prod/global-state/taon-global-state/taon-global-state.constants.ts +0 -9
- package/lib-prod/global-state/taon-global-state/taon-global-state.controller.ts +0 -44
- package/lib-prod/global-state/taon-global-state/taon-global-state.entity.ts +0 -40
- package/lib-prod/global-state/taon-global-state/taon-global-state.middleware.ts +0 -12
- package/lib-prod/global-state/taon-global-state/taon-global-state.models.ts +0 -48
- package/lib-prod/global-state/taon-global-state/taon-global-state.provider.ts +0 -16
- package/lib-prod/global-state/taon-global-state/taon-global-state.repository.ts +0 -47
- package/lib-prod/global-state/taon-global-state/taon-global-state.subscriber.ts +0 -18
- package/lib-prod/global-state/taon-global-state/taon-global-state.utils.ts +0 -21
- package/lib-prod/global-state/taon-transaction-registry/index.ts +0 -11
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.abstract.context.ts +0 -23
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.constants.ts +0 -7
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.controller.ts +0 -38
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.entity.ts +0 -54
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.middleware.ts +0 -12
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.models.ts +0 -6
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.provider.ts +0 -16
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.repository.ts +0 -29
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.subscriber.ts +0 -20
- package/lib-prod/global-state/taon-transaction-registry/taon-transaction-registry.utils.ts +0 -9
- package/lib-prod/helpers/class-helpers.ts +0 -315
- package/lib-prod/helpers/clone-obj.ts +0 -24
- package/lib-prod/helpers/taon-helpers.ts +0 -181
- package/lib-prod/index._auto-generated_.ts +0 -5
- package/lib-prod/index.ts +0 -323
- package/lib-prod/inject.ts +0 -111
- package/lib-prod/lib-info.md +0 -8
- package/lib-prod/migrations/index.ts +0 -2
- package/lib-prod/migrations/migrations-info.md +0 -6
- package/lib-prod/migrations/migrations_index._auto-generated_.ts +0 -5
- package/lib-prod/models.ts +0 -427
- package/lib-prod/orm/columns.ts +0 -121
- package/lib-prod/orm/index.ts +0 -62
- package/lib-prod/realtime/realtime-client.ts +0 -288
- package/lib-prod/realtime/realtime-core.ts +0 -134
- package/lib-prod/realtime/realtime-server.ts +0 -398
- package/lib-prod/realtime/realtime-strategy/index.ts +0 -4
- package/lib-prod/realtime/realtime-strategy/realtime-strategy-ipc.ts +0 -344
- package/lib-prod/realtime/realtime-strategy/realtime-strategy-mock.ts +0 -349
- package/lib-prod/realtime/realtime-strategy/realtime-strategy-socket-io.ts +0 -30
- package/lib-prod/realtime/realtime-strategy/realtime-strategy.ts +0 -21
- package/lib-prod/realtime/realtime-subs-manager.ts +0 -127
- package/lib-prod/realtime/realtime.models.ts +0 -33
- package/lib-prod/symbols.ts +0 -136
- package/lib-prod/ui/index.ts +0 -1
- package/lib-prod/ui/taon-admin-mode-configuration/index.ts +0 -1
- package/lib-prod/validators.ts +0 -103
|
@@ -0,0 +1,2033 @@
|
|
|
1
|
+
import { URL } from "url";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import { ipcMain } from "electron";
|
|
4
|
+
import { JSON10 } from "json10/lib-prod";
|
|
5
|
+
import { walk } from "lodash-walk-object/lib-prod";
|
|
6
|
+
import { Resource, RestHeaders, Mapping__NS__decode, Mapping__NS__encode } from "ng2-rest/lib-prod";
|
|
7
|
+
import { from } from "rxjs";
|
|
8
|
+
import { EventSubscriber } from "taon-typeorm/lib-prod";
|
|
9
|
+
import { Entity as TypeormEntity } from "taon-typeorm/lib-prod";
|
|
10
|
+
import {
|
|
11
|
+
DataSource
|
|
12
|
+
} from "taon-typeorm/lib-prod";
|
|
13
|
+
import { path, requireDefault } from "tnp-core/lib-prod";
|
|
14
|
+
import { config } from "tnp-core/lib-prod";
|
|
15
|
+
import { CoreModels__NS__TaonHttpErrorCustomProp } from "tnp-core/lib-prod";
|
|
16
|
+
import { fse, http, https } from "tnp-core/lib-prod";
|
|
17
|
+
import { Utils__NS__uniqArray, UtilsOs__NS__getRealHomeDir, UtilsOs__NS__isBrowser, UtilsOs__NS__isElectron, UtilsOs__NS__isNode, UtilsOs__NS__isRunningInCliMode, UtilsOs__NS__isRunningInDocker, UtilsOs__NS__isWebSQL } from "tnp-core/lib-prod";
|
|
18
|
+
import { crossPlatformPath } from "tnp-core/lib-prod";
|
|
19
|
+
import { ___NS__cloneDeep, ___NS__first, ___NS__isBoolean, ___NS__isFunction, ___NS__isNil, ___NS__isObject, ___NS__isString, ___NS__isUndefined, ___NS__last, ___NS__set, ___NS__slice, ___NS__snakeCase, ___NS__startCase, Helpers__NS__error, Helpers__NS__exists, Helpers__NS__info, Helpers__NS__log, Helpers__NS__mkdirp, Helpers__NS__throwError, Helpers__NS__writeFile } from "tnp-core/lib-prod";
|
|
20
|
+
import { apiPrefix } from "./constants";
|
|
21
|
+
import { ContextDbMigrations } from "./context-db-migrations";
|
|
22
|
+
import { DITaonContainer } from "./dependency-injection/di-container";
|
|
23
|
+
import { EntityProcess } from "./entity-process";
|
|
24
|
+
import { getResponseValue } from "./get-response-value";
|
|
25
|
+
import { ClassHelpers__NS__asyncHandler, ClassHelpers__NS__getControllerConfigs, ClassHelpers__NS__getMethodsNames, ClassHelpers__NS__getName, ClassHelpers__NS__getOrginalClass } from "./helpers/class-helpers";
|
|
26
|
+
import { TaonHelpers__NS__fillUpTo, TaonHelpers__NS__firstStringOrElemFromArray, TaonHelpers__NS__getExpressPath, TaonHelpers__NS__ipcKeyNameRequest, TaonHelpers__NS__ipcKeyNameResponse, TaonHelpers__NS__isGoodPath, TaonHelpers__NS__parseJSONwithStringJSONs, TaonHelpers__NS__tryTransformParam, TaonHelpers__NS__websqlMocks } from "./helpers/taon-helpers";
|
|
27
|
+
import { Models__NS__ClassType, Models__NS__ClassTypeKey, Models__NS__DatabaseConfig, Models__NS__DatabasesFolder } from "./models";
|
|
28
|
+
import { RealtimeCore } from "./realtime/realtime-core";
|
|
29
|
+
import { Symbols__NS__classMethodsNames, Symbols__NS__classNameStaticProperty, Symbols__NS__ctxInClassOrClassObj, Symbols__NS__fullClassNameStaticProperty, Symbols__NS__metadata, Symbols__NS__old, Symbols__NS__orignalClass } from "./symbols";
|
|
30
|
+
let bodyParser;
|
|
31
|
+
let cookieParser;
|
|
32
|
+
let cors;
|
|
33
|
+
let express;
|
|
34
|
+
let methodOverride;
|
|
35
|
+
let expressSession;
|
|
36
|
+
bodyParser = requireDefault("body-parser");
|
|
37
|
+
cookieParser = requireDefault("cookie-parser");
|
|
38
|
+
cors = requireDefault("cors");
|
|
39
|
+
express = requireDefault("express");
|
|
40
|
+
methodOverride = requireDefault("method-override");
|
|
41
|
+
expressSession = requireDefault("express-session");
|
|
42
|
+
class EndpointContext {
|
|
43
|
+
constructor(originalConfig, configFn, cloneOptions) {
|
|
44
|
+
this.originalConfig = originalConfig;
|
|
45
|
+
this.configFn = configFn;
|
|
46
|
+
this.cloneOptions = cloneOptions;
|
|
47
|
+
this.cloneOptions = this.cloneOptions || {};
|
|
48
|
+
this.isRunningInsideDocker = UtilsOs__NS__isRunningInDocker();
|
|
49
|
+
}
|
|
50
|
+
//#region fields
|
|
51
|
+
//#region fields / use mariadb mysql in docker
|
|
52
|
+
/**
|
|
53
|
+
* JUST FOR TESTING PURPOSES
|
|
54
|
+
*/
|
|
55
|
+
USE_MARIADB_MYSQL_IN_DOCKER = false;
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region fields / flags
|
|
58
|
+
disabledRealtime = false;
|
|
59
|
+
/**
|
|
60
|
+
* check whether context is inited
|
|
61
|
+
* (with init() function )
|
|
62
|
+
*/
|
|
63
|
+
inited = false;
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region fields / db migrations
|
|
66
|
+
dbMigrations = new ContextDbMigrations(this);
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region fields / local instance obj symbol
|
|
69
|
+
localInstaceObjSymbol = Symbol("localInstaceObjSymbol");
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region fields / all instances of classes from context
|
|
72
|
+
/**
|
|
73
|
+
* all instances of classes from context
|
|
74
|
+
* key is class name
|
|
75
|
+
*/
|
|
76
|
+
allClassesInstances = {};
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region fields / class instances by name
|
|
79
|
+
classInstancesByNameObj = {};
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region fields / obj with classes instances arr
|
|
82
|
+
objWithClassesInstancesArr = {};
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region fields / active routes
|
|
85
|
+
activeRoutes = [];
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region fields / typeorm repositories
|
|
88
|
+
//#region @websql
|
|
89
|
+
repos = /* @__PURE__ */ new Map();
|
|
90
|
+
//#endregion
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region fields / source context
|
|
93
|
+
get sourceContext() {
|
|
94
|
+
return this.cloneOptions?.sourceContext;
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region fields / skip writing server routes
|
|
98
|
+
skipWritingServerRoutes = false;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region fields / types from contexts
|
|
101
|
+
injectableTypesfromContexts = [
|
|
102
|
+
Models__NS__ClassType.CONTROLLER,
|
|
103
|
+
Models__NS__ClassType.PROVIDER,
|
|
104
|
+
Models__NS__ClassType.MIDDLEWARE,
|
|
105
|
+
Models__NS__ClassType.REPOSITORY,
|
|
106
|
+
Models__NS__ClassType.SUBSCRIBER,
|
|
107
|
+
Models__NS__ClassType.MIGRATION
|
|
108
|
+
];
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region fields / all types from contexts
|
|
111
|
+
allTypesfromContexts = [
|
|
112
|
+
...this.injectableTypesfromContexts,
|
|
113
|
+
Models__NS__ClassType.ENTITY
|
|
114
|
+
];
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region fields / express app
|
|
117
|
+
expressApp = {};
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region fields / server tcp udp
|
|
120
|
+
serverTcpUdp;
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region fields / database config
|
|
123
|
+
databaseConfig;
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region fields / mode
|
|
126
|
+
mode;
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region fields / only migration start
|
|
129
|
+
onlyMigrationRun = false;
|
|
130
|
+
onlyMigrationRevertToTimestamp = void 0;
|
|
131
|
+
get isRunOrRevertOnlyMigrationAppStart() {
|
|
132
|
+
return !!(this.onlyMigrationRun || this.onlyMigrationRevertToTimestamp);
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region fields / session
|
|
136
|
+
session;
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region fields / connection
|
|
139
|
+
connection;
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region fields / entities triggers
|
|
142
|
+
entitiesTriggers = {};
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region fields / realtime
|
|
145
|
+
realtime;
|
|
146
|
+
get realtimeClient() {
|
|
147
|
+
return this.realtime.client;
|
|
148
|
+
}
|
|
149
|
+
get realtimeServer() {
|
|
150
|
+
return this.realtime.server;
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region fields / config
|
|
154
|
+
/**
|
|
155
|
+
* available after init()
|
|
156
|
+
*/
|
|
157
|
+
config;
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region fields / logs
|
|
160
|
+
get logHttp() {
|
|
161
|
+
if (___NS__isObject(this.config?.logs)) {
|
|
162
|
+
return !!this.config.logs.http;
|
|
163
|
+
}
|
|
164
|
+
return this.config?.logs === true;
|
|
165
|
+
}
|
|
166
|
+
get logRealtime() {
|
|
167
|
+
if (___NS__isObject(this.config?.logs)) {
|
|
168
|
+
return !!this.config.logs.realtime;
|
|
169
|
+
}
|
|
170
|
+
return this.config?.logs === true;
|
|
171
|
+
}
|
|
172
|
+
get logFramework() {
|
|
173
|
+
if (___NS__isObject(this.config?.logs)) {
|
|
174
|
+
return !!this.config.logs.framework;
|
|
175
|
+
}
|
|
176
|
+
return this.config?.logs === true;
|
|
177
|
+
}
|
|
178
|
+
get logRoutes() {
|
|
179
|
+
if (___NS__isObject(this.config?.logs)) {
|
|
180
|
+
return !!this.config.logs.routes;
|
|
181
|
+
}
|
|
182
|
+
return this.config?.logs === true;
|
|
183
|
+
}
|
|
184
|
+
get logDb() {
|
|
185
|
+
if (___NS__isObject(this.config?.logs)) {
|
|
186
|
+
return !!this.config.logs.db;
|
|
187
|
+
}
|
|
188
|
+
return this.config?.logs === true;
|
|
189
|
+
}
|
|
190
|
+
get logMigrations() {
|
|
191
|
+
if (___NS__isObject(this.config?.logs)) {
|
|
192
|
+
return !!this.config.logs.migrations;
|
|
193
|
+
}
|
|
194
|
+
return this.config?.logs === true;
|
|
195
|
+
}
|
|
196
|
+
//#endregion
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region constructor
|
|
199
|
+
/**
|
|
200
|
+
* Inside docker there is not need for https secure server
|
|
201
|
+
*/
|
|
202
|
+
isRunningInsideDocker = false;
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region methods & getters / init
|
|
205
|
+
async init(options) {
|
|
206
|
+
const {
|
|
207
|
+
initFromRecrusiveContextResovle,
|
|
208
|
+
onlyMigrationRun,
|
|
209
|
+
onlyMigrationRevertToTimestamp
|
|
210
|
+
} = options || {};
|
|
211
|
+
this.inited = true;
|
|
212
|
+
this.onlyMigrationRun = onlyMigrationRun;
|
|
213
|
+
this.onlyMigrationRevertToTimestamp = onlyMigrationRevertToTimestamp;
|
|
214
|
+
this.config = this.configFn({});
|
|
215
|
+
if (___NS__isObject(this.config.database)) {
|
|
216
|
+
this.config.database = Models__NS__DatabaseConfig.from(
|
|
217
|
+
this.config.database
|
|
218
|
+
).databaseConfigTypeORM;
|
|
219
|
+
}
|
|
220
|
+
this.config.host = this.host === null ? void 0 : this.host;
|
|
221
|
+
if (this.cloneOptions.overrideHost && !this.cloneOptions.useAsRemoteContext) {
|
|
222
|
+
this.config.host = this.cloneOptions.overrideHost;
|
|
223
|
+
}
|
|
224
|
+
if (this.cloneOptions.overrideRemoteHost && this.cloneOptions.useAsRemoteContext) {
|
|
225
|
+
this.config.host = this.cloneOptions.overrideRemoteHost;
|
|
226
|
+
}
|
|
227
|
+
if (this.config.host && !this.config.host.startsWith("http://") && !this.config.host.startsWith("https://")) {
|
|
228
|
+
Helpers__NS__throwError(
|
|
229
|
+
`[taon-config] Your${this.host ? " remote" : ""} 'host' must start with http:// or https://`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
if (___NS__isUndefined(this.config.useIpcWhenElectron)) {
|
|
233
|
+
this.config.useIpcWhenElectron = true;
|
|
234
|
+
}
|
|
235
|
+
this.skipWritingServerRoutes = ___NS__isBoolean(
|
|
236
|
+
this.config.skipWritingServerRoutes
|
|
237
|
+
) ? this.config.skipWritingServerRoutes : false;
|
|
238
|
+
if (this.config.host) {
|
|
239
|
+
this.mode = "backend-frontend(tcp+udp)";
|
|
240
|
+
}
|
|
241
|
+
if (this.isRemoteHost) {
|
|
242
|
+
this.mode = "remote-backend(tcp+udp)";
|
|
243
|
+
}
|
|
244
|
+
if (this.config.useIpcWhenElectron && UtilsOs__NS__isElectron) {
|
|
245
|
+
if (UtilsOs__NS__isWebSQL) {
|
|
246
|
+
this.mode = "backend-frontend(websql-electron)";
|
|
247
|
+
} else {
|
|
248
|
+
this.mode = "backend-frontend(ipc-electron)";
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (!this.mode && !this.config.abstract) {
|
|
252
|
+
const errMsg = `You need to provide host property or useIpcWhenElectron or mark it as abstract`;
|
|
253
|
+
Helpers__NS__error(
|
|
254
|
+
`[taon][Context=${this.contextName}]: ${errMsg}`,
|
|
255
|
+
false,
|
|
256
|
+
true
|
|
257
|
+
);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
}
|
|
260
|
+
if (this.config.database === true) {
|
|
261
|
+
this.logFramework && console.log(`
|
|
262
|
+
|
|
263
|
+
ASSIGNING AUTO GENERATED DATABASE CONFIG
|
|
264
|
+
|
|
265
|
+
`);
|
|
266
|
+
this.databaseConfig = this.getAutoGeneratedConfig();
|
|
267
|
+
} else if (___NS__isObject(this.config.database)) {
|
|
268
|
+
this.logFramework && console.log(`
|
|
269
|
+
|
|
270
|
+
OVERRIDE DATABASE CONFIG FROM CONFIGURATION
|
|
271
|
+
|
|
272
|
+
`);
|
|
273
|
+
this.databaseConfig = this.getAutoGeneratedConfig();
|
|
274
|
+
walk.Object(
|
|
275
|
+
this.config.database,
|
|
276
|
+
(value, lodashPath) => {
|
|
277
|
+
if (___NS__isNil(value) || ___NS__isFunction(value) || ___NS__isObject(value)) {
|
|
278
|
+
} else {
|
|
279
|
+
this.logFramework && console.info(
|
|
280
|
+
`Overriding database config: ${lodashPath}=${value}`
|
|
281
|
+
);
|
|
282
|
+
___NS__set(this.databaseConfig, lodashPath, value);
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
walkGetters: false
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
if (this.config.session) {
|
|
291
|
+
this.session = ___NS__cloneDeep(this.config.session);
|
|
292
|
+
const oneHour = 1e3 * 60 * 60 * 1;
|
|
293
|
+
if (!this.session.cookieMaxAge) {
|
|
294
|
+
this.session.cookieMaxAge = oneHour;
|
|
295
|
+
}
|
|
296
|
+
axios.defaults.withCredentials = true;
|
|
297
|
+
}
|
|
298
|
+
this.config.contexts = this.config.contexts || {};
|
|
299
|
+
this.config.entities = this.config.entities || {};
|
|
300
|
+
this.config.controllers = this.config.controllers || {};
|
|
301
|
+
this.config.repositories = this.config.repositories || {};
|
|
302
|
+
this.config.providers = this.config.providers || {};
|
|
303
|
+
this.config.subscribers = this.config.subscribers || {};
|
|
304
|
+
this.config.migrations = this.config.migrations || {};
|
|
305
|
+
this.config.entities = {
|
|
306
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
307
|
+
Models__NS__ClassType.ENTITY
|
|
308
|
+
),
|
|
309
|
+
...this.config.entities
|
|
310
|
+
};
|
|
311
|
+
this.config.controllers = {
|
|
312
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
313
|
+
Models__NS__ClassType.CONTROLLER
|
|
314
|
+
),
|
|
315
|
+
...this.config.controllers
|
|
316
|
+
};
|
|
317
|
+
this.config.providers = {
|
|
318
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
319
|
+
Models__NS__ClassType.PROVIDER
|
|
320
|
+
),
|
|
321
|
+
...this.config.providers
|
|
322
|
+
};
|
|
323
|
+
this.config.middlewares = {
|
|
324
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
325
|
+
Models__NS__ClassType.MIDDLEWARE
|
|
326
|
+
),
|
|
327
|
+
...this.config.middlewares
|
|
328
|
+
};
|
|
329
|
+
this.config.subscribers = {
|
|
330
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
331
|
+
Models__NS__ClassType.SUBSCRIBER
|
|
332
|
+
),
|
|
333
|
+
...this.config.subscribers
|
|
334
|
+
};
|
|
335
|
+
this.config.repositories = {
|
|
336
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
337
|
+
Models__NS__ClassType.REPOSITORY
|
|
338
|
+
),
|
|
339
|
+
...this.config.repositories
|
|
340
|
+
};
|
|
341
|
+
this.config.migrations = {
|
|
342
|
+
...await this.getRecrusiveClassesfromContextsObj(
|
|
343
|
+
Models__NS__ClassType.MIGRATION
|
|
344
|
+
),
|
|
345
|
+
...this.config.migrations
|
|
346
|
+
};
|
|
347
|
+
this.config.controllers = this.cloneClassesObjWithNewMetadata({
|
|
348
|
+
classesInput: this.config.controllers,
|
|
349
|
+
config: this.config,
|
|
350
|
+
ctx: this,
|
|
351
|
+
classType: Models__NS__ClassType.CONTROLLER
|
|
352
|
+
});
|
|
353
|
+
this.config.repositories = this.cloneClassesObjWithNewMetadata({
|
|
354
|
+
classesInput: this.config.repositories,
|
|
355
|
+
config: this.config,
|
|
356
|
+
ctx: this,
|
|
357
|
+
classType: Models__NS__ClassType.REPOSITORY
|
|
358
|
+
});
|
|
359
|
+
this.config.providers = this.cloneClassesObjWithNewMetadata({
|
|
360
|
+
classesInput: this.config.providers,
|
|
361
|
+
config: this.config,
|
|
362
|
+
ctx: this,
|
|
363
|
+
classType: Models__NS__ClassType.PROVIDER
|
|
364
|
+
});
|
|
365
|
+
this.config.middlewares = this.cloneClassesObjWithNewMetadata({
|
|
366
|
+
classesInput: this.config.middlewares,
|
|
367
|
+
config: this.config,
|
|
368
|
+
ctx: this,
|
|
369
|
+
classType: Models__NS__ClassType.MIDDLEWARE
|
|
370
|
+
});
|
|
371
|
+
this.config.subscribers = this.cloneClassesObjWithNewMetadata({
|
|
372
|
+
classesInput: this.config.subscribers,
|
|
373
|
+
config: this.config,
|
|
374
|
+
ctx: this,
|
|
375
|
+
classType: Models__NS__ClassType.SUBSCRIBER
|
|
376
|
+
});
|
|
377
|
+
this.config.migrations = this.cloneClassesObjWithNewMetadata({
|
|
378
|
+
classesInput: this.config.migrations,
|
|
379
|
+
config: this.config,
|
|
380
|
+
ctx: this,
|
|
381
|
+
classType: Models__NS__ClassType.MIGRATION
|
|
382
|
+
});
|
|
383
|
+
for (const classTypeName of this.injectableTypesfromContexts) {
|
|
384
|
+
this.classInstancesByNameObj[classTypeName] = {};
|
|
385
|
+
this.objWithClassesInstancesArr[classTypeName] = [];
|
|
386
|
+
}
|
|
387
|
+
for (const classTypeName of this.injectableTypesfromContexts) {
|
|
388
|
+
await this.createInstances(
|
|
389
|
+
this.config[Models__NS__ClassTypeKey[classTypeName]],
|
|
390
|
+
classTypeName
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
if (!this.isRunOrRevertOnlyMigrationAppStart) {
|
|
394
|
+
if (this.mode === "backend-frontend(tcp+udp)" && !this.config.abstract) {
|
|
395
|
+
this.expressApp = express();
|
|
396
|
+
if (process.env.NODE_ENV === "production") {
|
|
397
|
+
this.expressApp.set("trust proxy", 1);
|
|
398
|
+
}
|
|
399
|
+
await this.initBackendMiddlewares();
|
|
400
|
+
await this.initCustomBackendMiddlewares();
|
|
401
|
+
const shouldStartHttpsSecureServer = this.isHttpServer && !this.isRunningInsideDocker;
|
|
402
|
+
this.logFramework && Helpers__NS__info(`
|
|
403
|
+
|
|
404
|
+
Starting server ${shouldStartHttpsSecureServer ? "with" : "without"} HTTPS secure server
|
|
405
|
+
|
|
406
|
+
`);
|
|
407
|
+
this.serverTcpUdp = shouldStartHttpsSecureServer ? new https.Server(
|
|
408
|
+
{
|
|
409
|
+
key: this.config.https?.key,
|
|
410
|
+
cert: this.config.https?.cert
|
|
411
|
+
},
|
|
412
|
+
this.expressApp
|
|
413
|
+
) : new http.Server(this.expressApp);
|
|
414
|
+
this.publicAssets.forEach((asset) => {
|
|
415
|
+
this.expressApp.use(
|
|
416
|
+
asset.serverPath,
|
|
417
|
+
express.static(asset.locationOnDisk)
|
|
418
|
+
);
|
|
419
|
+
});
|
|
420
|
+
await this.initCustomClientMiddlewares();
|
|
421
|
+
}
|
|
422
|
+
if (!this.config.abstract) {
|
|
423
|
+
this.disabledRealtime = this.config.disabledRealtime;
|
|
424
|
+
if (!this.host) {
|
|
425
|
+
throw `
|
|
426
|
+
|
|
427
|
+
host is required for context initialization..
|
|
428
|
+
(Or maybe you forgot mark ${this.config.contextName} context as abstract?)
|
|
429
|
+
|
|
430
|
+
`;
|
|
431
|
+
}
|
|
432
|
+
this.logRealtime && Helpers__NS__info(
|
|
433
|
+
`[ctx=${this.contextName}] Init Realtime for ${this.mode}`
|
|
434
|
+
);
|
|
435
|
+
this.realtime = new RealtimeCore(this);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (this.config.abstract) {
|
|
439
|
+
this.logFramework && Helpers__NS__info(
|
|
440
|
+
`[taon] Create abstract context: ${this.config.contextName}`
|
|
441
|
+
);
|
|
442
|
+
} else {
|
|
443
|
+
if (this.isRemoteHost) {
|
|
444
|
+
this.logFramework && Helpers__NS__info(
|
|
445
|
+
`[taon] Create context for remote host: ${this.config.host}`
|
|
446
|
+
);
|
|
447
|
+
} else {
|
|
448
|
+
this.logFramework && Helpers__NS__info(`[taon] Create context for host: ${this.config.host}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
Object.keys(this.config).forEach((key) => {
|
|
452
|
+
this.originalConfig[key] = this.config[key];
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region methods & getters / get auto generated config
|
|
457
|
+
getAutoGeneratedConfig() {
|
|
458
|
+
this.logFramework && console.log(`
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
IS RUNNING IN DOCKER: ${this.isRunningInsideDocker}
|
|
462
|
+
|
|
463
|
+
`);
|
|
464
|
+
let databaseConfig = Models__NS__DatabaseConfig.from({});
|
|
465
|
+
const tcpUdpDatabaseSqliteRelativeFileLocation = `${Models__NS__DatabasesFolder}/db-${this.contextName}.sqlite`;
|
|
466
|
+
if (this.isRunningInsideDocker) {
|
|
467
|
+
if (this.USE_MARIADB_MYSQL_IN_DOCKER) {
|
|
468
|
+
} else {
|
|
469
|
+
this.logFramework && console.log(`
|
|
470
|
+
|
|
471
|
+
USING GENERATED CONFIG FOR SQLJS IN DOCKER
|
|
472
|
+
|
|
473
|
+
`);
|
|
474
|
+
const locationOfTheDatabase = crossPlatformPath([
|
|
475
|
+
process.cwd(),
|
|
476
|
+
`db-${this.contextName}.sqlite`
|
|
477
|
+
]);
|
|
478
|
+
databaseConfig = databaseConfig = Models__NS__DatabaseConfig.from({
|
|
479
|
+
location: tcpUdpDatabaseSqliteRelativeFileLocation,
|
|
480
|
+
type: "sqljs",
|
|
481
|
+
useLocalForage: false,
|
|
482
|
+
recreateMode: "PRESERVE_DATA+MIGRATIONS",
|
|
483
|
+
logging: true
|
|
484
|
+
});
|
|
485
|
+
if (!fse.existsSync(locationOfTheDatabase)) {
|
|
486
|
+
databaseConfig.recreateMode = "DROP_DB+MIGRATIONS";
|
|
487
|
+
}
|
|
488
|
+
this.logFramework && console.log(`
|
|
489
|
+
location of database: ${locationOfTheDatabase}
|
|
490
|
+
db file exists: ${fse.existsSync(locationOfTheDatabase)}
|
|
491
|
+
synchronize: ${databaseConfig.synchronize}
|
|
492
|
+
dropSchema: ${databaseConfig.dropSchema}
|
|
493
|
+
`);
|
|
494
|
+
}
|
|
495
|
+
} else {
|
|
496
|
+
this.logFramework && Helpers__NS__info(
|
|
497
|
+
`[taon][database] Automatically resolving database config for mode ${this.mode}`
|
|
498
|
+
);
|
|
499
|
+
switch (this.mode) {
|
|
500
|
+
//#region resolve database config for backend-frontend(ipc-electron)
|
|
501
|
+
case "backend-frontend(ipc-electron)":
|
|
502
|
+
let dbLocationInOs;
|
|
503
|
+
if (UtilsOs__NS__isElectron) {
|
|
504
|
+
dbLocationInOs = crossPlatformPath([
|
|
505
|
+
UtilsOs__NS__getRealHomeDir(),
|
|
506
|
+
`.taon/databases-for-electron-apps/${this.appId || ___NS__snakeCase(process.cwd()).replace(/\_/, ".")}/${this.contextName}.sqlite`
|
|
507
|
+
]);
|
|
508
|
+
if (!Helpers__NS__exists(path.dirname(dbLocationInOs))) {
|
|
509
|
+
Helpers__NS__mkdirp(path.dirname(dbLocationInOs));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
databaseConfig = Models__NS__DatabaseConfig.from({
|
|
513
|
+
location: UtilsOs__NS__isElectron ? dbLocationInOs : `db-${this.contextName}.sqlite`,
|
|
514
|
+
type: "sqljs",
|
|
515
|
+
recreateMode: "DROP_DB+MIGRATIONS",
|
|
516
|
+
logging: this.logDb
|
|
517
|
+
});
|
|
518
|
+
break;
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region resolve database config for mode backend-frontend(websql)
|
|
521
|
+
case "backend-frontend(websql-electron)":
|
|
522
|
+
case "backend-frontend(websql)":
|
|
523
|
+
let keepWebsqlDbDataAfterReload = false;
|
|
524
|
+
databaseConfig = databaseConfig = Models__NS__DatabaseConfig.from({
|
|
525
|
+
location: `db-${this.contextName}.sqlite`,
|
|
526
|
+
type: "sqljs",
|
|
527
|
+
useLocalForage: true,
|
|
528
|
+
// !!window['localforage'], // TODO this need to be checked in runtime
|
|
529
|
+
recreateMode: keepWebsqlDbDataAfterReload ? "PRESERVE_DATA+MIGRATIONS" : "DROP_DB+MIGRATIONS",
|
|
530
|
+
logging: this.logDb
|
|
531
|
+
});
|
|
532
|
+
break;
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region resolve database config for mode backend-frontend(tcp+udp)
|
|
535
|
+
case "backend-frontend(tcp+udp)":
|
|
536
|
+
databaseConfig = Models__NS__DatabaseConfig.from({
|
|
537
|
+
database: `context-db-${this.contextName}`,
|
|
538
|
+
location: tcpUdpDatabaseSqliteRelativeFileLocation,
|
|
539
|
+
type: "sqljs",
|
|
540
|
+
recreateMode: "DROP_DB+MIGRATIONS",
|
|
541
|
+
logging: this.logDb
|
|
542
|
+
});
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return databaseConfig.databaseConfigTypeORM;
|
|
547
|
+
}
|
|
548
|
+
//#endregion
|
|
549
|
+
//#region methods & getters / start server
|
|
550
|
+
async startServer() {
|
|
551
|
+
if (this.isRemoteHost || this.isRunOrRevertOnlyMigrationAppStart) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
if (this.mode === "backend-frontend(tcp+udp)") {
|
|
555
|
+
return await new Promise((resolve) => {
|
|
556
|
+
if (this.isRunningInsideDocker) {
|
|
557
|
+
this.serverTcpUdp.listen(Number(this.uriPort), "0.0.0.0", () => {
|
|
558
|
+
this.logFramework && Helpers__NS__log(
|
|
559
|
+
`[ctx=${this.contextName}] Express server (inside docker) started 0.0.0.0:${this.uriPort}`
|
|
560
|
+
);
|
|
561
|
+
this.logFramework && Helpers__NS__log(`[taon][express-server]listening on port: ${this.uriPort}, hostname: ${this.uriPathname},
|
|
562
|
+
address: ${this.uriProtocol}//localhost:${this.uriPort}${this.uriPathname}
|
|
563
|
+
ExpressJS mode: ${this.expressApp.settings.env}
|
|
564
|
+
`);
|
|
565
|
+
resolve(void 0);
|
|
566
|
+
});
|
|
567
|
+
} else {
|
|
568
|
+
this.serverTcpUdp.listen(Number(this.uriPort), () => {
|
|
569
|
+
this.logFramework && Helpers__NS__log(
|
|
570
|
+
`[ctx=${this.contextName}] Express server (inside nodejs app) started on localhost:${this.uriPort}`
|
|
571
|
+
);
|
|
572
|
+
this.logFramework && Helpers__NS__log(`[taon][express-server]listening on port: ${this.uriPort}, hostname: ${this.uriPathname},
|
|
573
|
+
address: ${this.uriProtocol}//localhost:${this.uriPort}${this.uriPathname}
|
|
574
|
+
expressJS mode: ${this.expressApp.settings.env}
|
|
575
|
+
`);
|
|
576
|
+
resolve(void 0);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
} else {
|
|
581
|
+
this.logFramework && Helpers__NS__info("Ipc communication enable instead tcp/upd");
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
//#endregion
|
|
585
|
+
//#region methods & getters / display express routes
|
|
586
|
+
displayRoutes(app) {
|
|
587
|
+
const routes = [];
|
|
588
|
+
app._router?.stack.forEach(function(middleware) {
|
|
589
|
+
if (middleware.route) {
|
|
590
|
+
const methods = [];
|
|
591
|
+
for (let method in middleware.route.methods) {
|
|
592
|
+
if (middleware.route.methods[method]) {
|
|
593
|
+
methods.push(method.toUpperCase());
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
routes.push({ path: middleware.route.path, methods });
|
|
597
|
+
} else if (middleware.name === "router") {
|
|
598
|
+
middleware.handle.stack.forEach(function(handler) {
|
|
599
|
+
const methods = [];
|
|
600
|
+
for (let method in handler.route.methods) {
|
|
601
|
+
if (handler.route.methods[method]) {
|
|
602
|
+
methods.push(method.toUpperCase());
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
routes.push({ path: handler.route.path, methods });
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
console.log(routes);
|
|
610
|
+
}
|
|
611
|
+
//#endregion
|
|
612
|
+
//#region methods & getters / mode allows database creation
|
|
613
|
+
get modeAllowsDatabaseCreation() {
|
|
614
|
+
return this.mode === "backend-frontend(tcp+udp)" || this.mode === "backend-frontend(websql)" || this.mode === "backend-frontend(ipc-electron)";
|
|
615
|
+
}
|
|
616
|
+
//#endregion
|
|
617
|
+
//#region methods & getters / clone class
|
|
618
|
+
cloneClassWithNewMetadata = ({
|
|
619
|
+
TaonBaseClass,
|
|
620
|
+
className,
|
|
621
|
+
config: config2,
|
|
622
|
+
ctx,
|
|
623
|
+
classType
|
|
624
|
+
}) => {
|
|
625
|
+
const cloneClass = () => {
|
|
626
|
+
if (TaonBaseClass[Symbols__NS__fullClassNameStaticProperty] === `${ctx.contextName}.${className}`) {
|
|
627
|
+
return TaonBaseClass;
|
|
628
|
+
}
|
|
629
|
+
return class extends TaonBaseClass {
|
|
630
|
+
// static ['_'] = TaonBaseClass['_'];
|
|
631
|
+
// @ts-ignore
|
|
632
|
+
static [Symbols__NS__orignalClass] = TaonBaseClass;
|
|
633
|
+
// @ts-ignore
|
|
634
|
+
static [Symbols__NS__fullClassNameStaticProperty] = `${ctx.contextName}.${className}`;
|
|
635
|
+
// @ts-ignore
|
|
636
|
+
static [Symbols__NS__classNameStaticProperty] = className;
|
|
637
|
+
static [Symbols__NS__ctxInClassOrClassObj] = ctx;
|
|
638
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
639
|
+
static __getFullPathForClass__(arr = []) {
|
|
640
|
+
const name = this[Symbols__NS__fullClassNameStaticProperty];
|
|
641
|
+
arr.push(name);
|
|
642
|
+
if (this[Symbols__NS__orignalClass] && // @ts-ignore
|
|
643
|
+
this[Symbols__NS__orignalClass].__getFullPathForClass__) {
|
|
644
|
+
this[Symbols__NS__orignalClass].__getFullPathForClass__(arr);
|
|
645
|
+
}
|
|
646
|
+
return arr.join("/");
|
|
647
|
+
}
|
|
648
|
+
static get fullPathForClass() {
|
|
649
|
+
return this.__getFullPathForClass__();
|
|
650
|
+
}
|
|
651
|
+
[Symbols__NS__ctxInClassOrClassObj] = ctx;
|
|
652
|
+
// You can override prototype properties or methods here if needed
|
|
653
|
+
// static properties override allowed
|
|
654
|
+
};
|
|
655
|
+
};
|
|
656
|
+
const cloneClassFunction = cloneClass();
|
|
657
|
+
return cloneClassFunction;
|
|
658
|
+
};
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region methods & getters / clone classes obj with new metadata
|
|
661
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
662
|
+
cloneClassesObjWithNewMetadata = ({
|
|
663
|
+
classesInput,
|
|
664
|
+
config: config2,
|
|
665
|
+
ctx,
|
|
666
|
+
classType
|
|
667
|
+
}) => {
|
|
668
|
+
const classes = {};
|
|
669
|
+
for (const key of Object.keys(classesInput || {})) {
|
|
670
|
+
const TaonBaseClass = classesInput[key];
|
|
671
|
+
if (!TaonBaseClass) {
|
|
672
|
+
Helpers__NS__error(`Class ${key} is not defined in context ${ctx.contextName}
|
|
673
|
+
|
|
674
|
+
Please check if you have correct import in context file
|
|
675
|
+
|
|
676
|
+
`);
|
|
677
|
+
}
|
|
678
|
+
var className = Reflect.getMetadata(
|
|
679
|
+
Symbols__NS__metadata.className,
|
|
680
|
+
TaonBaseClass
|
|
681
|
+
);
|
|
682
|
+
className = className || key;
|
|
683
|
+
TaonBaseClass[Symbols__NS__classNameStaticProperty] = className;
|
|
684
|
+
const clonedClass = this.cloneClassWithNewMetadata({
|
|
685
|
+
TaonBaseClass,
|
|
686
|
+
className,
|
|
687
|
+
config: config2,
|
|
688
|
+
ctx,
|
|
689
|
+
classType
|
|
690
|
+
});
|
|
691
|
+
classes[className] = clonedClass;
|
|
692
|
+
}
|
|
693
|
+
return classes;
|
|
694
|
+
};
|
|
695
|
+
//#endregion
|
|
696
|
+
//#region methods & getters / get recursive classes from contexts
|
|
697
|
+
async getRecrusiveClassesfromContextsObj(classType) {
|
|
698
|
+
const arr = await this.getRecrusiveClassesfromContexts(classType);
|
|
699
|
+
return arr.reduce((acc, c) => {
|
|
700
|
+
acc[ClassHelpers__NS__getName(c)] = c;
|
|
701
|
+
return acc;
|
|
702
|
+
}, {});
|
|
703
|
+
}
|
|
704
|
+
async getRecrusiveClassesfromContexts(classType, arr = []) {
|
|
705
|
+
const contexts = Object.values(this.config.contexts || {});
|
|
706
|
+
for (const ctx of contexts) {
|
|
707
|
+
const ref = await ctx.__ref();
|
|
708
|
+
const classesInput = ref.getClassFunBy(classType);
|
|
709
|
+
const clonedClasses = Object.values(
|
|
710
|
+
this.cloneClassesObjWithNewMetadata({
|
|
711
|
+
classesInput,
|
|
712
|
+
config: this.config,
|
|
713
|
+
ctx: this,
|
|
714
|
+
classType
|
|
715
|
+
})
|
|
716
|
+
);
|
|
717
|
+
clonedClasses.forEach((c) => arr.push(c));
|
|
718
|
+
await ref.getRecrusiveClassesfromContexts(classType, arr);
|
|
719
|
+
}
|
|
720
|
+
return arr;
|
|
721
|
+
}
|
|
722
|
+
//#endregion
|
|
723
|
+
//#region methods & getters / get class instances by class type
|
|
724
|
+
getClassInstanceObjBy(classType) {
|
|
725
|
+
return this.classInstancesByNameObj[classType];
|
|
726
|
+
}
|
|
727
|
+
//#endregion
|
|
728
|
+
//#region methods & getters / get class instances arr
|
|
729
|
+
getClassesInstancesArrBy(classType) {
|
|
730
|
+
return this.objWithClassesInstancesArr[classType];
|
|
731
|
+
}
|
|
732
|
+
//#endregion
|
|
733
|
+
//#region methods & getters / inject
|
|
734
|
+
inject(ctor, options) {
|
|
735
|
+
const className = ClassHelpers__NS__getName(ctor);
|
|
736
|
+
const locaInstanceConstructorArgs = options.locaInstanceConstructorArgs || [];
|
|
737
|
+
if (this.isCLassType(Models__NS__ClassType.REPOSITORY, ctor)) {
|
|
738
|
+
options.localInstance = true;
|
|
739
|
+
}
|
|
740
|
+
if (options?.localInstance) {
|
|
741
|
+
const ctxClassFn = this.getClassFunByClassName(className);
|
|
742
|
+
let entityName = "";
|
|
743
|
+
const entityFn = ___NS__first(locaInstanceConstructorArgs);
|
|
744
|
+
const entity = entityFn && entityFn();
|
|
745
|
+
entityName = entity && ClassHelpers__NS__getName(entity) || "";
|
|
746
|
+
if (!options.contextClassInstance[this.localInstaceObjSymbol]) {
|
|
747
|
+
options.contextClassInstance[this.localInstaceObjSymbol] = {};
|
|
748
|
+
}
|
|
749
|
+
const instanceKey = className + (entityName ? `.${entityName}` : "");
|
|
750
|
+
const existed = options.contextClassInstance[this.localInstaceObjSymbol][instanceKey];
|
|
751
|
+
if (existed) {
|
|
752
|
+
return existed;
|
|
753
|
+
}
|
|
754
|
+
if (!ctxClassFn) {
|
|
755
|
+
throw new Error(`Not able to inject "${className}" inside context "${this.contextName}"
|
|
756
|
+
|
|
757
|
+
Make sure they share the same context or import context where "${className}" is defined.
|
|
758
|
+
|
|
759
|
+
`);
|
|
760
|
+
}
|
|
761
|
+
const injectedInstance = new ctxClassFn(
|
|
762
|
+
...locaInstanceConstructorArgs
|
|
763
|
+
);
|
|
764
|
+
options.contextClassInstance[this.localInstaceObjSymbol][instanceKey] = injectedInstance;
|
|
765
|
+
return injectedInstance;
|
|
766
|
+
}
|
|
767
|
+
const contextScopeInstance = this.allClassesInstances[className];
|
|
768
|
+
return contextScopeInstance;
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* alias for inject
|
|
772
|
+
*/
|
|
773
|
+
getInstanceBy(ctor) {
|
|
774
|
+
return this.inject(ctor, {
|
|
775
|
+
localInstance: false,
|
|
776
|
+
parentInstanceThatWillGetInjectedStuff: this
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
//#endregion
|
|
780
|
+
//#region methods & getters / check if context initialized
|
|
781
|
+
checkIfContextInitialized() {
|
|
782
|
+
if (___NS__isUndefined(this.config)) {
|
|
783
|
+
throw new Error(`Please check if your context has been initialized.
|
|
784
|
+
|
|
785
|
+
// ...
|
|
786
|
+
await Context.initialize();
|
|
787
|
+
// ...
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
`);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
//#endregion
|
|
794
|
+
//#region methods & getters / get class function by class type name
|
|
795
|
+
getClassFunBy(classType) {
|
|
796
|
+
this.checkIfContextInitialized();
|
|
797
|
+
switch (classType) {
|
|
798
|
+
case Models__NS__ClassType.CONTROLLER:
|
|
799
|
+
return this.config.controllers;
|
|
800
|
+
case Models__NS__ClassType.ENTITY:
|
|
801
|
+
return this.config.entities;
|
|
802
|
+
case Models__NS__ClassType.PROVIDER:
|
|
803
|
+
return this.config.providers;
|
|
804
|
+
case Models__NS__ClassType.MIDDLEWARE:
|
|
805
|
+
return this.config.middlewares;
|
|
806
|
+
case Models__NS__ClassType.REPOSITORY:
|
|
807
|
+
return this.config.repositories;
|
|
808
|
+
case Models__NS__ClassType.SUBSCRIBER:
|
|
809
|
+
return this.config.subscribers;
|
|
810
|
+
case Models__NS__ClassType.MIGRATION:
|
|
811
|
+
return this.config.migrations;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
isCLassType(classType, classFn) {
|
|
815
|
+
return !!this.getClassFunBy(classType)[ClassHelpers__NS__getName(classFn)];
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Only for injectable types
|
|
819
|
+
* Only for classType: CONTROLLER, REPOSITORY, PROVIDER, MIDDLEWARES
|
|
820
|
+
*/
|
|
821
|
+
getClassFunByClassName(className) {
|
|
822
|
+
for (const classTypeName of this.allTypesfromContexts) {
|
|
823
|
+
const classesForInjectableType = this.config[Models__NS__ClassTypeKey[classTypeName]];
|
|
824
|
+
if (classesForInjectableType[className]) {
|
|
825
|
+
return classesForInjectableType[className];
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
getClassFunByClass(classFunction) {
|
|
830
|
+
const className = ClassHelpers__NS__getName(classFunction);
|
|
831
|
+
return this.getClassFunByClassName(className);
|
|
832
|
+
}
|
|
833
|
+
getClassFunByArr(classType) {
|
|
834
|
+
return Object.values(this.getClassFunBy(classType) || {});
|
|
835
|
+
}
|
|
836
|
+
//#endregion
|
|
837
|
+
//#region methods & getters / create class instances
|
|
838
|
+
async createInstances(classes, classType) {
|
|
839
|
+
for (const classFn of [
|
|
840
|
+
// ...recrusiveValuesFromContext,
|
|
841
|
+
...Object.values(classes)
|
|
842
|
+
]) {
|
|
843
|
+
const instance = DITaonContainer.resolve(classFn);
|
|
844
|
+
const classInstancesByNameObj = this.classInstancesByNameObj[classType];
|
|
845
|
+
const className = ClassHelpers__NS__getName(classFn);
|
|
846
|
+
classInstancesByNameObj[className] = instance;
|
|
847
|
+
this.config[Models__NS__ClassTypeKey[classType]][className] = classFn;
|
|
848
|
+
this.objWithClassesInstancesArr[classType].push(instance);
|
|
849
|
+
this.allClassesInstances[className] = instance;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
//#endregion
|
|
853
|
+
//#region methods & getters / init classes
|
|
854
|
+
async initClasses() {
|
|
855
|
+
if (this.isRemoteHost) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
for (const classFun of this.getClassFunByArr(
|
|
859
|
+
Models__NS__ClassType.ENTITY
|
|
860
|
+
)) {
|
|
861
|
+
const repo = await this.connection.getRepository(
|
|
862
|
+
ClassHelpers__NS__getOrginalClass(classFun)
|
|
863
|
+
);
|
|
864
|
+
this.repos.set(ClassHelpers__NS__getName(classFun), repo);
|
|
865
|
+
}
|
|
866
|
+
for (const classTypeName of [
|
|
867
|
+
Models__NS__ClassType.MIDDLEWARE,
|
|
868
|
+
Models__NS__ClassType.PROVIDER,
|
|
869
|
+
Models__NS__ClassType.REPOSITORY,
|
|
870
|
+
Models__NS__ClassType.CONTROLLER,
|
|
871
|
+
Models__NS__ClassType.ENTITY,
|
|
872
|
+
Models__NS__ClassType.MIGRATION
|
|
873
|
+
]) {
|
|
874
|
+
for (const classFun of this.getClassFunByArr(classTypeName)) {
|
|
875
|
+
if (___NS__isFunction(classFun._)) {
|
|
876
|
+
await classFun._();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
for (const classTypeName of [
|
|
881
|
+
Models__NS__ClassType.MIDDLEWARE,
|
|
882
|
+
Models__NS__ClassType.PROVIDER,
|
|
883
|
+
Models__NS__ClassType.REPOSITORY,
|
|
884
|
+
Models__NS__ClassType.CONTROLLER,
|
|
885
|
+
Models__NS__ClassType.MIGRATION
|
|
886
|
+
]) {
|
|
887
|
+
for (const ctrl of this.getClassesInstancesArrBy(classTypeName)) {
|
|
888
|
+
if (___NS__isFunction(ctrl._)) {
|
|
889
|
+
await ctrl._();
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
//#endregion
|
|
895
|
+
//#region methods & getters / is active on
|
|
896
|
+
isActiveOn(classInstance) {
|
|
897
|
+
let contextRef = classInstance[Symbols__NS__ctxInClassOrClassObj];
|
|
898
|
+
return this === contextRef;
|
|
899
|
+
}
|
|
900
|
+
//#endregion
|
|
901
|
+
//#region methods & getters / uri
|
|
902
|
+
get frontendHostUri() {
|
|
903
|
+
const url = this.config?.frontendHost?.startsWith("http") ? this.config.frontendHost : `${globalThis?.location?.protocol || "http:"}//${this.config?.frontendHost}`;
|
|
904
|
+
const uri = new URL(url.replace(/\/$/, ""));
|
|
905
|
+
return uri;
|
|
906
|
+
}
|
|
907
|
+
get uri() {
|
|
908
|
+
const url = this.host ? new URL(this.host) : void 0;
|
|
909
|
+
return url;
|
|
910
|
+
}
|
|
911
|
+
//#endregion
|
|
912
|
+
//#region methods & getters / host uri protocol
|
|
913
|
+
get uriProtocol() {
|
|
914
|
+
return this.uri?.protocol;
|
|
915
|
+
}
|
|
916
|
+
//#endregion
|
|
917
|
+
//#region methods & getters / host uri origin
|
|
918
|
+
/**
|
|
919
|
+
* Examples
|
|
920
|
+
* http://localhost:3000
|
|
921
|
+
* https://localhost (from localhost:80) *
|
|
922
|
+
*/
|
|
923
|
+
get uriOrigin() {
|
|
924
|
+
return this.uri?.origin;
|
|
925
|
+
}
|
|
926
|
+
//#endregion
|
|
927
|
+
//#region methods & getters / host uri pathname
|
|
928
|
+
/**
|
|
929
|
+
* Exampels
|
|
930
|
+
* http://localhost:3000/path/to/somewhere
|
|
931
|
+
* https://localhost/path/to/somewhere (from localhost:80)
|
|
932
|
+
*/
|
|
933
|
+
// get uriOriginWithPathname(): string | undefined {
|
|
934
|
+
// return this.uri?.origin
|
|
935
|
+
// ? this.uri?.origin + this.uriPathnameOrNothingIfRoot.replace(/\/$/, '')
|
|
936
|
+
// : undefined;
|
|
937
|
+
// }
|
|
938
|
+
get uriPathname() {
|
|
939
|
+
return this.uri?.pathname;
|
|
940
|
+
}
|
|
941
|
+
//#endregion
|
|
942
|
+
//#region methods & getters / uri pathname or nothing if root
|
|
943
|
+
/**
|
|
944
|
+
* Examples
|
|
945
|
+
* http://localhost:3000/path/to/somewhere -> '/path/to/somewhere'
|
|
946
|
+
* http://localhost:3000 -> '' #
|
|
947
|
+
* https://localhost/path/to/ -> '/path/to/somewhere' # remove last slash
|
|
948
|
+
*/
|
|
949
|
+
get uriPathnameOrNothingIfRoot() {
|
|
950
|
+
const isNonRootProperPathName = this.uri?.pathname && this.uri.pathname !== "/";
|
|
951
|
+
return isNonRootProperPathName ? this.uri.pathname.replace(/\/$/, "") : "";
|
|
952
|
+
}
|
|
953
|
+
//#endregion
|
|
954
|
+
//#region methods & getters / port from uri
|
|
955
|
+
get uriPort() {
|
|
956
|
+
if (!this.uri?.origin?.includes("localhost")) {
|
|
957
|
+
return this.config?.hostPortNumber?.toString();
|
|
958
|
+
}
|
|
959
|
+
return this.uri?.port;
|
|
960
|
+
}
|
|
961
|
+
// TODO do i need 2 getters for port?
|
|
962
|
+
/**
|
|
963
|
+
* Port from uri as number
|
|
964
|
+
* @returns {Number | undefined}
|
|
965
|
+
*/
|
|
966
|
+
get port() {
|
|
967
|
+
return this.uri?.port ? Number(this.uriPort) : void 0;
|
|
968
|
+
}
|
|
969
|
+
//#endregion
|
|
970
|
+
//#region methods & getters / is https server
|
|
971
|
+
get isHttpServer() {
|
|
972
|
+
return this.uriProtocol === "https:";
|
|
973
|
+
}
|
|
974
|
+
//#endregion
|
|
975
|
+
//#region methods & getters / is remote host
|
|
976
|
+
/**
|
|
977
|
+
* Check if context is for remote only
|
|
978
|
+
*/
|
|
979
|
+
get isRemoteHost() {
|
|
980
|
+
return !!this.cloneOptions?.useAsRemoteContext;
|
|
981
|
+
}
|
|
982
|
+
//#endregion
|
|
983
|
+
//#region methods & getters / context name
|
|
984
|
+
/**
|
|
985
|
+
* ipc/udp needs this
|
|
986
|
+
*/
|
|
987
|
+
get contextName() {
|
|
988
|
+
return this.config?.contextName || this.originalConfig?.contextName;
|
|
989
|
+
}
|
|
990
|
+
//#endregion
|
|
991
|
+
//#region methods & getters / context name for communication
|
|
992
|
+
/**
|
|
993
|
+
* ipc/udp needs this
|
|
994
|
+
*/
|
|
995
|
+
get contextNameForCommunication() {
|
|
996
|
+
let contextName = this.contextName;
|
|
997
|
+
if (this.isRemoteHost) {
|
|
998
|
+
if (this.sourceContext?.contextName) {
|
|
999
|
+
contextName = this.sourceContext?.contextName;
|
|
1000
|
+
} else {
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
return contextName;
|
|
1004
|
+
}
|
|
1005
|
+
//#endregion
|
|
1006
|
+
//#region methods & getters / get context type
|
|
1007
|
+
/**
|
|
1008
|
+
* Check context type
|
|
1009
|
+
*/
|
|
1010
|
+
get contextType() {
|
|
1011
|
+
if (this.config.abstract) {
|
|
1012
|
+
return "abstract";
|
|
1013
|
+
}
|
|
1014
|
+
if (this.host) {
|
|
1015
|
+
return this.isRemoteHost ? "remote" : "normal";
|
|
1016
|
+
}
|
|
1017
|
+
return "invalid";
|
|
1018
|
+
}
|
|
1019
|
+
//#endregion
|
|
1020
|
+
//#region methods & getters / current working directory
|
|
1021
|
+
get cwd() {
|
|
1022
|
+
return this.config.cwd || process.cwd();
|
|
1023
|
+
}
|
|
1024
|
+
//#endregion
|
|
1025
|
+
//#region methods & getters / active context
|
|
1026
|
+
get activeContext() {
|
|
1027
|
+
return this.config.activeContext || null;
|
|
1028
|
+
}
|
|
1029
|
+
//#endregion
|
|
1030
|
+
//#region methods & getters / app id
|
|
1031
|
+
get appId() {
|
|
1032
|
+
return this.config.appId;
|
|
1033
|
+
}
|
|
1034
|
+
//#endregion
|
|
1035
|
+
//#region methods & getters / public assets
|
|
1036
|
+
get publicAssets() {
|
|
1037
|
+
return this.config?.publicAssets || [];
|
|
1038
|
+
}
|
|
1039
|
+
//#endregion
|
|
1040
|
+
//#region methods & getters / is production mode
|
|
1041
|
+
get isProductionMode() {
|
|
1042
|
+
return this.config.productionMode;
|
|
1043
|
+
}
|
|
1044
|
+
//#endregion
|
|
1045
|
+
//#region methods & getters / host
|
|
1046
|
+
get host() {
|
|
1047
|
+
return this.config.host;
|
|
1048
|
+
}
|
|
1049
|
+
//#endregion
|
|
1050
|
+
//#region methods & getters / origin
|
|
1051
|
+
get origin() {
|
|
1052
|
+
return this.uri?.origin;
|
|
1053
|
+
}
|
|
1054
|
+
//#endregion
|
|
1055
|
+
//#region methods & getters / init subscribers
|
|
1056
|
+
async initSubscribers() {
|
|
1057
|
+
if (this.isRemoteHost) {
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
const subscriberClasses = this.getClassFunByArr(
|
|
1061
|
+
Models__NS__ClassType.SUBSCRIBER
|
|
1062
|
+
);
|
|
1063
|
+
for (const subscriberClassFn of subscriberClasses) {
|
|
1064
|
+
const options = Reflect.getMetadata(
|
|
1065
|
+
Symbols__NS__metadata.options.subscriber,
|
|
1066
|
+
subscriberClassFn
|
|
1067
|
+
);
|
|
1068
|
+
EventSubscriber()(subscriberClassFn);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
//#endregion
|
|
1072
|
+
//#region methods & getters / init entities
|
|
1073
|
+
async initEntities() {
|
|
1074
|
+
if (this.isRemoteHost) {
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
const entities = this.getClassFunByArr(Models__NS__ClassType.ENTITY);
|
|
1078
|
+
for (const entity of entities) {
|
|
1079
|
+
const options = Reflect.getMetadata(
|
|
1080
|
+
Symbols__NS__metadata.options.entity,
|
|
1081
|
+
entity
|
|
1082
|
+
);
|
|
1083
|
+
const createTable = ___NS__isUndefined(options.createTable) ? true : options.createTable;
|
|
1084
|
+
const nameForEntity = ClassHelpers__NS__getName(entity);
|
|
1085
|
+
if (createTable) {
|
|
1086
|
+
this.logDb && console.info(
|
|
1087
|
+
`[taon][typeorm] create table for entity "${nameForEntity}" ? '${createTable}'`
|
|
1088
|
+
);
|
|
1089
|
+
TypeormEntity(nameForEntity)(entity);
|
|
1090
|
+
} else {
|
|
1091
|
+
this.logDb && console.info(
|
|
1092
|
+
`[taon][typeorm] create table for entity "${nameForEntity}" ? '${createTable}'`
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
//#endregion
|
|
1098
|
+
//#region methods & getters / destroy
|
|
1099
|
+
async destroy() {
|
|
1100
|
+
if (this.connection) {
|
|
1101
|
+
await this.connection?.destroy();
|
|
1102
|
+
delete this.connection;
|
|
1103
|
+
}
|
|
1104
|
+
if (this.serverTcpUdp) {
|
|
1105
|
+
await new Promise((resolve) => {
|
|
1106
|
+
this.serverTcpUdp?.close(() => {
|
|
1107
|
+
resolve(true);
|
|
1108
|
+
});
|
|
1109
|
+
});
|
|
1110
|
+
delete this.serverTcpUdp;
|
|
1111
|
+
}
|
|
1112
|
+
delete this.expressApp;
|
|
1113
|
+
}
|
|
1114
|
+
//#endregion
|
|
1115
|
+
//#region methods & getters / init connection
|
|
1116
|
+
async initDatabaseConnection() {
|
|
1117
|
+
if (this.isRemoteHost || !this.databaseConfig) {
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
const entities = this.getClassFunByArr(Models__NS__ClassType.ENTITY).map(
|
|
1121
|
+
(entityFn) => {
|
|
1122
|
+
return ClassHelpers__NS__getOrginalClass(entityFn);
|
|
1123
|
+
}
|
|
1124
|
+
);
|
|
1125
|
+
const subscribers = this.getClassFunByArr(Models__NS__ClassType.SUBSCRIBER);
|
|
1126
|
+
let autoSave = false;
|
|
1127
|
+
if (!___NS__isNil(this.databaseConfig.autoSave)) {
|
|
1128
|
+
autoSave = this.databaseConfig.autoSave;
|
|
1129
|
+
} else {
|
|
1130
|
+
if (this.USE_MARIADB_MYSQL_IN_DOCKER) {
|
|
1131
|
+
autoSave = !this.isRunningInsideDocker;
|
|
1132
|
+
} else {
|
|
1133
|
+
autoSave = true;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const dataSourceDbConfig = ___NS__isObject(this.databaseConfig) ? {
|
|
1137
|
+
type: this.databaseConfig.type,
|
|
1138
|
+
port: this.databaseConfig.databasePort,
|
|
1139
|
+
host: this.databaseConfig.databaseHost,
|
|
1140
|
+
database: this.databaseConfig.database,
|
|
1141
|
+
username: this.databaseConfig.databaseUsername,
|
|
1142
|
+
password: this.databaseConfig.databasePassword,
|
|
1143
|
+
useLocalForage: this.databaseConfig.useLocalForage,
|
|
1144
|
+
// I am not using typeorm migration system
|
|
1145
|
+
entities,
|
|
1146
|
+
subscribers,
|
|
1147
|
+
synchronize: this.isRunOrRevertOnlyMigrationAppStart ? false : this.databaseConfig.synchronize,
|
|
1148
|
+
autoSave,
|
|
1149
|
+
dropSchema: this.isRunOrRevertOnlyMigrationAppStart ? false : this.databaseConfig.dropSchema,
|
|
1150
|
+
logging: !!this.databaseConfig.logging,
|
|
1151
|
+
location: this.databaseConfig.location
|
|
1152
|
+
} : {};
|
|
1153
|
+
this.logFramework && console.log(
|
|
1154
|
+
`[Context: "${this.contextName}"] dataSourceDbConfig`,
|
|
1155
|
+
dataSourceDbConfig
|
|
1156
|
+
);
|
|
1157
|
+
if (this.modeAllowsDatabaseCreation && this.databaseConfig) {
|
|
1158
|
+
this.logDb && this.logFramework && Helpers__NS__info("[taon][database] prepare typeorm connection...");
|
|
1159
|
+
try {
|
|
1160
|
+
const connection = new DataSource(dataSourceDbConfig);
|
|
1161
|
+
this.connection = connection;
|
|
1162
|
+
await this.connection.initialize();
|
|
1163
|
+
} catch (error) {
|
|
1164
|
+
console.error(
|
|
1165
|
+
`[taon][typeorm] Error while initializing connection for ${this.contextName}, ERROR STARTED `
|
|
1166
|
+
);
|
|
1167
|
+
console.error(error?.stack || "< No stack trace > ");
|
|
1168
|
+
console.error(error?.message || error);
|
|
1169
|
+
console.error(
|
|
1170
|
+
`[taon][typeorm] Error while initializing connection for ${this.contextName}, ERROR ENDS `
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
if (!this.connection?.isInitialized) {
|
|
1174
|
+
console.log("WRONG CONFIG", dataSourceDbConfig);
|
|
1175
|
+
throw new Error(`Something wrong with connection init in ${this.mode}`);
|
|
1176
|
+
process.exit(1);
|
|
1177
|
+
}
|
|
1178
|
+
if (this.logDb || this.logFramework) {
|
|
1179
|
+
console.info(
|
|
1180
|
+
`
|
|
1181
|
+
|
|
1182
|
+
CONTECTION OK for ${this.contextName} - ${this.mode}
|
|
1183
|
+
|
|
1184
|
+
[taon][typeorm] db prepration done.. db initialize=${this.connection?.isInitialized}
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
`,
|
|
1188
|
+
// dataSourceDbConfig,
|
|
1189
|
+
{ "this.connection": !!this.connection }
|
|
1190
|
+
);
|
|
1191
|
+
console.log(
|
|
1192
|
+
`Database file location: ${this.connection.options.database}`
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
} else {
|
|
1196
|
+
Helpers__NS__info(`[taon][typeorm] Not initing db for mode ${this.mode}`);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
//#endregion
|
|
1200
|
+
//#region methods & getters / initialize metadata
|
|
1201
|
+
//#region methods & getters / update class calculate path
|
|
1202
|
+
updateCalculatedPathsForControllers(rawConfigs, classConfig, controllerClassFn) {
|
|
1203
|
+
const parentsCalculatedPath = ___NS__slice(rawConfigs, 1).reverse().map((bc) => {
|
|
1204
|
+
if (TaonHelpers__NS__isGoodPath(bc.path)) {
|
|
1205
|
+
return bc.path;
|
|
1206
|
+
}
|
|
1207
|
+
return bc.className;
|
|
1208
|
+
}).join("/");
|
|
1209
|
+
const contextNameForCommunication = this.contextNameForCommunication;
|
|
1210
|
+
if (TaonHelpers__NS__isGoodPath(classConfig.path)) {
|
|
1211
|
+
classConfig.calculatedPath = classConfig.path;
|
|
1212
|
+
} else {
|
|
1213
|
+
classConfig.calculatedPath = `${this.uriPathnameOrNothingIfRoot}/${apiPrefix}/${contextNameForCommunication}/tcp${parentsCalculatedPath}/${ClassHelpers__NS__getName(controllerClassFn)}`.replace(/\/\//g, "/").split("/").reduce((acc, bc) => {
|
|
1214
|
+
return ___NS__last(acc) === bc ? acc : [...acc, bc];
|
|
1215
|
+
}, []).join("/");
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
//#endregion
|
|
1219
|
+
//#region methods & getters / dedupe class configs
|
|
1220
|
+
mergeControllerMethodsConfigs(rawConfigs, classConfig, controllerClassFn) {
|
|
1221
|
+
const currentControllerMethodsConfig = classConfig.methods;
|
|
1222
|
+
___NS__slice(rawConfigs, 1).forEach((bc) => {
|
|
1223
|
+
const parentControllerMethods = ___NS__cloneDeep(bc.methods);
|
|
1224
|
+
for (const methodsName in parentControllerMethods) {
|
|
1225
|
+
if (parentControllerMethods.hasOwnProperty(methodsName)) {
|
|
1226
|
+
if (!currentControllerMethodsConfig[methodsName]) {
|
|
1227
|
+
const methodConfig = parentControllerMethods[methodsName];
|
|
1228
|
+
currentControllerMethodsConfig[methodsName] = methodConfig;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
//#endregion
|
|
1235
|
+
async initControllersHook(ctxStorage) {
|
|
1236
|
+
if (this.isRunOrRevertOnlyMigrationAppStart) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
const allControllers = this.getClassFunByArr(Models__NS__ClassType.CONTROLLER);
|
|
1240
|
+
for (const controllerClassFn of allControllers) {
|
|
1241
|
+
const instance = this.getInstanceBy(
|
|
1242
|
+
controllerClassFn
|
|
1243
|
+
);
|
|
1244
|
+
if (___NS__isFunction(instance.afterAllCtxInited)) {
|
|
1245
|
+
await instance.afterAllCtxInited({ ctxStorage });
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
async initControllers() {
|
|
1250
|
+
if (this.isRunOrRevertOnlyMigrationAppStart) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
const allControllers = this.getClassFunByArr(Models__NS__ClassType.CONTROLLER);
|
|
1254
|
+
for (const controllerClassFn of allControllers) {
|
|
1255
|
+
controllerClassFn[Symbols__NS__classMethodsNames] = ClassHelpers__NS__getMethodsNames(controllerClassFn);
|
|
1256
|
+
const rawConfigs = ClassHelpers__NS__getControllerConfigs(controllerClassFn);
|
|
1257
|
+
const classConfig = rawConfigs[0];
|
|
1258
|
+
this.updateCalculatedPathsForControllers(
|
|
1259
|
+
rawConfigs,
|
|
1260
|
+
classConfig,
|
|
1261
|
+
controllerClassFn
|
|
1262
|
+
);
|
|
1263
|
+
this.mergeControllerMethodsConfigs(
|
|
1264
|
+
rawConfigs,
|
|
1265
|
+
classConfig,
|
|
1266
|
+
controllerClassFn
|
|
1267
|
+
);
|
|
1268
|
+
classConfig.calculatedMiddlewaresControllerObj = {};
|
|
1269
|
+
[...rawConfigs].reverse().forEach((rc) => {
|
|
1270
|
+
if (___NS__isFunction(rc.middlewares)) {
|
|
1271
|
+
classConfig.calculatedMiddlewaresControllerObj = rc.middlewares({
|
|
1272
|
+
parentMiddlewares: classConfig.calculatedMiddlewaresControllerObj,
|
|
1273
|
+
className(middlewareClass) {
|
|
1274
|
+
return ClassHelpers__NS__getName(controllerClassFn);
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
if (!UtilsOs__NS__isRunningInCliMode()) {
|
|
1280
|
+
this.logHttp && console.groupCollapsed(
|
|
1281
|
+
`[taon][express-server] routes [${classConfig.className}]`
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
const methodNames = Object.keys(classConfig.methods);
|
|
1285
|
+
for (const methodName of methodNames) {
|
|
1286
|
+
const methodConfig = classConfig.methods[methodName];
|
|
1287
|
+
let calculatedMiddlewaresMethodObj = {};
|
|
1288
|
+
[...rawConfigs].reverse().forEach((rc) => {
|
|
1289
|
+
if (rc.methods[methodName]) {
|
|
1290
|
+
const parentMethodConfig = rc.methods[methodName];
|
|
1291
|
+
if (___NS__isFunction(parentMethodConfig.middlewares)) {
|
|
1292
|
+
calculatedMiddlewaresMethodObj = parentMethodConfig.middlewares({
|
|
1293
|
+
parentMiddlewares: calculatedMiddlewaresMethodObj,
|
|
1294
|
+
className(middlewareClass) {
|
|
1295
|
+
return ClassHelpers__NS__getName(controllerClassFn);
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
methodConfig.calculatedMiddlewaresMethodObj = {
|
|
1302
|
+
...calculatedMiddlewaresMethodObj,
|
|
1303
|
+
...classConfig.calculatedMiddlewaresControllerObj
|
|
1304
|
+
};
|
|
1305
|
+
methodConfig.calculatedMiddlewares = Object.values(
|
|
1306
|
+
methodConfig.calculatedMiddlewaresMethodObj || {}
|
|
1307
|
+
);
|
|
1308
|
+
const httpMethodType = methodConfig.type;
|
|
1309
|
+
const globalPathPart = this.isRunningInsideDocker || !this.frontendHostUri?.origin?.includes("localhost") ? `${this.uriPathnameOrNothingIfRoot.replace(
|
|
1310
|
+
/\/$/,
|
|
1311
|
+
""
|
|
1312
|
+
)}/${apiPrefix}/${this.contextName}`.replace(/\/\//, "/") : "";
|
|
1313
|
+
const expressPath = methodConfig.global ? `${globalPathPart}/${methodConfig.path?.replace(
|
|
1314
|
+
/\/$/,
|
|
1315
|
+
""
|
|
1316
|
+
)}`.replace(/\/\//, "/") : TaonHelpers__NS__getExpressPath(classConfig, methodConfig);
|
|
1317
|
+
if (UtilsOs__NS__isNode || UtilsOs__NS__isWebSQL) {
|
|
1318
|
+
const route = this.initServer(
|
|
1319
|
+
httpMethodType,
|
|
1320
|
+
methodConfig,
|
|
1321
|
+
classConfig,
|
|
1322
|
+
expressPath,
|
|
1323
|
+
controllerClassFn
|
|
1324
|
+
);
|
|
1325
|
+
this.activeRoutes.push({
|
|
1326
|
+
expressPath: route.expressPath,
|
|
1327
|
+
method: route.method
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
const shouldInitClient = UtilsOs__NS__isBrowser || this.isRemoteHost || UtilsOs__NS__isWebSQL;
|
|
1331
|
+
if (shouldInitClient) {
|
|
1332
|
+
await this.initClient(
|
|
1333
|
+
controllerClassFn,
|
|
1334
|
+
httpMethodType,
|
|
1335
|
+
methodConfig,
|
|
1336
|
+
expressPath
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
if (!UtilsOs__NS__isRunningInCliMode()) {
|
|
1341
|
+
this.logHttp && console.groupEnd();
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
//#endregion
|
|
1346
|
+
//#region methods & getters / write active routes
|
|
1347
|
+
writeActiveRoutes() {
|
|
1348
|
+
if (this.isRemoteHost || this.isRunOrRevertOnlyMigrationAppStart) {
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
const troutes = Utils__NS__uniqArray(
|
|
1352
|
+
this.activeRoutes.map((f) => {
|
|
1353
|
+
return `${f.method} ${f.expressPath}`;
|
|
1354
|
+
})
|
|
1355
|
+
).map((f) => {
|
|
1356
|
+
const [method, expressPath] = f.split(" ");
|
|
1357
|
+
return `
|
|
1358
|
+
### ${___NS__startCase(___NS__last(expressPath.split("/")))}
|
|
1359
|
+
` + TaonHelpers__NS__fillUpTo(method.toUpperCase() + " ", 10) + this.uriOrigin + expressPath;
|
|
1360
|
+
});
|
|
1361
|
+
const routes = [
|
|
1362
|
+
...["", `# ROUTES FOR HOST ${this.uriOrigin} `],
|
|
1363
|
+
...troutes
|
|
1364
|
+
].join("\n");
|
|
1365
|
+
const fileName = crossPlatformPath([
|
|
1366
|
+
//#region @backend
|
|
1367
|
+
process.cwd(),
|
|
1368
|
+
//#endregion
|
|
1369
|
+
`routes/routes-${this.config.contextName}.rest`
|
|
1370
|
+
]);
|
|
1371
|
+
this.logFramework && console.log(`[taon] routes file: ${fileName} `);
|
|
1372
|
+
this.logRoutes && console.log(routes);
|
|
1373
|
+
if (!UtilsOs__NS__isElectron && !this.skipWritingServerRoutes) {
|
|
1374
|
+
Helpers__NS__writeFile(fileName, routes);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
//#endregion
|
|
1378
|
+
//#region methods & getters / middlewares
|
|
1379
|
+
get middlewares() {
|
|
1380
|
+
return this.config.middlewares || [];
|
|
1381
|
+
}
|
|
1382
|
+
//#endregion
|
|
1383
|
+
//#region methods & getters / init middlewares
|
|
1384
|
+
async initCustomClientMiddlewares() {
|
|
1385
|
+
const middlewares = this.getClassesInstancesArrBy(
|
|
1386
|
+
Models__NS__ClassType.MIDDLEWARE
|
|
1387
|
+
).map((f) => f).filter((f) => ___NS__isFunction(f.interceptClient));
|
|
1388
|
+
middlewares.forEach((middlewareInstanceName) => {
|
|
1389
|
+
const contextName = this.contextName;
|
|
1390
|
+
const interceptorName = `${contextName}-${ClassHelpers__NS__getName(
|
|
1391
|
+
middlewareInstanceName
|
|
1392
|
+
)}`;
|
|
1393
|
+
Resource.request.interceptors.set(interceptorName, {
|
|
1394
|
+
intercept: ({ req, next }) => {
|
|
1395
|
+
const url = new URL(req.url);
|
|
1396
|
+
if (url.pathname.startsWith(
|
|
1397
|
+
`${this.uriPathnameOrNothingIfRoot}/${apiPrefix}/${contextName}/`
|
|
1398
|
+
)) {
|
|
1399
|
+
return middlewareInstanceName.interceptClient({
|
|
1400
|
+
req,
|
|
1401
|
+
next
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
return next.handle(req);
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
async initCustomBackendMiddlewares() {
|
|
1410
|
+
const app = this.expressApp;
|
|
1411
|
+
const middlewares = this.getClassesInstancesArrBy(
|
|
1412
|
+
Models__NS__ClassType.MIDDLEWARE
|
|
1413
|
+
);
|
|
1414
|
+
for (const middleware of middlewares) {
|
|
1415
|
+
const middlewareInstance = middleware;
|
|
1416
|
+
if (___NS__isFunction(middlewareInstance.interceptServer)) {
|
|
1417
|
+
const middlewareFn = ClassHelpers__NS__asyncHandler(
|
|
1418
|
+
async (req, res, next) => {
|
|
1419
|
+
if (req.originalUrl.startsWith(
|
|
1420
|
+
`${this.uriPathnameOrNothingIfRoot}/${apiPrefix}/${this.contextName}/`
|
|
1421
|
+
)) {
|
|
1422
|
+
await middlewareInstance.interceptServer({
|
|
1423
|
+
req,
|
|
1424
|
+
res,
|
|
1425
|
+
next
|
|
1426
|
+
});
|
|
1427
|
+
} else {
|
|
1428
|
+
next();
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
);
|
|
1432
|
+
app.use(middlewareFn);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
async initBackendMiddlewares() {
|
|
1437
|
+
const app = this.expressApp;
|
|
1438
|
+
this.expressApp.get("/helloworld", (req, res) => {
|
|
1439
|
+
res.send(`Hello, world from context ${this.contextName}`);
|
|
1440
|
+
});
|
|
1441
|
+
app.use(bodyParser.urlencoded({ extended: true }));
|
|
1442
|
+
app.use(bodyParser.json());
|
|
1443
|
+
app.use(methodOverride());
|
|
1444
|
+
app.use(cookieParser());
|
|
1445
|
+
if (this.session) {
|
|
1446
|
+
Helpers__NS__info(
|
|
1447
|
+
"[taon][express-server] session enabled for this context " + this.contextName
|
|
1448
|
+
);
|
|
1449
|
+
const { cookieMaxAge } = this.session;
|
|
1450
|
+
const frontendHost = this.config.frontendHost;
|
|
1451
|
+
const sessionObj = {
|
|
1452
|
+
frontendHost,
|
|
1453
|
+
secret: "mysecretsessioncookithing",
|
|
1454
|
+
saveUninitialized: true,
|
|
1455
|
+
cookieMaxAge,
|
|
1456
|
+
secure: frontendHost.startsWith("https://"),
|
|
1457
|
+
resave: false
|
|
1458
|
+
};
|
|
1459
|
+
app.use(
|
|
1460
|
+
cors({
|
|
1461
|
+
credentials: true,
|
|
1462
|
+
origin: frontendHost
|
|
1463
|
+
})
|
|
1464
|
+
);
|
|
1465
|
+
app.use(expressSession(sessionObj));
|
|
1466
|
+
console.log(`
|
|
1467
|
+
|
|
1468
|
+
CORS ENABLED FOR SESSION
|
|
1469
|
+
|
|
1470
|
+
`);
|
|
1471
|
+
} else {
|
|
1472
|
+
this.logHttp && Helpers__NS__info(
|
|
1473
|
+
`[taon][express-server] session not enabled for this context '${this.contextName}'`
|
|
1474
|
+
);
|
|
1475
|
+
app.use(
|
|
1476
|
+
cors({
|
|
1477
|
+
// origin: "http://localhost:5555",
|
|
1478
|
+
// methods: ["GET", "POST"],
|
|
1479
|
+
// allowedHeaders: ["my-custom-header"],
|
|
1480
|
+
// credentials: true
|
|
1481
|
+
})
|
|
1482
|
+
);
|
|
1483
|
+
this.logHttp && console.log(`
|
|
1484
|
+
|
|
1485
|
+
CORS ENABLED WITHOUT SESSION
|
|
1486
|
+
|
|
1487
|
+
`);
|
|
1488
|
+
}
|
|
1489
|
+
(() => {
|
|
1490
|
+
app.use((req, res, next) => {
|
|
1491
|
+
res.set(
|
|
1492
|
+
"Access-Control-Expose-Headers",
|
|
1493
|
+
[
|
|
1494
|
+
"Content-Type",
|
|
1495
|
+
"Authorization",
|
|
1496
|
+
"X-Requested-With",
|
|
1497
|
+
Symbols__NS__old.X_TOTAL_COUNT,
|
|
1498
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER,
|
|
1499
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY,
|
|
1500
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_QUERY_PARAM
|
|
1501
|
+
].join(", ")
|
|
1502
|
+
);
|
|
1503
|
+
next();
|
|
1504
|
+
});
|
|
1505
|
+
})();
|
|
1506
|
+
}
|
|
1507
|
+
//#endregion
|
|
1508
|
+
//#region methods & getters / init methods node
|
|
1509
|
+
initServer(httpMethodType, methodConfig, classConfig, expressPath, target) {
|
|
1510
|
+
const middlewareHandlers = methodConfig.calculatedMiddlewares.map((middlewareClassFun) => {
|
|
1511
|
+
const middlewareInstance = this.getInstanceBy(
|
|
1512
|
+
middlewareClassFun
|
|
1513
|
+
);
|
|
1514
|
+
if (middlewareInstance && ___NS__isFunction(middlewareInstance.interceptServerMethod)) {
|
|
1515
|
+
const middlewareFn = ClassHelpers__NS__asyncHandler(
|
|
1516
|
+
async (req, res, next) => {
|
|
1517
|
+
await middlewareInstance.interceptServerMethod(
|
|
1518
|
+
{
|
|
1519
|
+
req,
|
|
1520
|
+
res,
|
|
1521
|
+
next
|
|
1522
|
+
},
|
|
1523
|
+
{
|
|
1524
|
+
methodName: methodConfig.methodName,
|
|
1525
|
+
expressPath,
|
|
1526
|
+
httpRequestType: methodConfig.type
|
|
1527
|
+
}
|
|
1528
|
+
);
|
|
1529
|
+
}
|
|
1530
|
+
);
|
|
1531
|
+
return middlewareFn;
|
|
1532
|
+
}
|
|
1533
|
+
}).filter((f) => !!f);
|
|
1534
|
+
const getResult = async (resolvedParams, req, res) => {
|
|
1535
|
+
const response = methodConfig.descriptor.value.apply(
|
|
1536
|
+
/**
|
|
1537
|
+
* Context for method @GET,@PUT etc.
|
|
1538
|
+
*/
|
|
1539
|
+
this.getInstanceBy(target),
|
|
1540
|
+
/**
|
|
1541
|
+
* Params for method @GET, @PUT etc.
|
|
1542
|
+
*/
|
|
1543
|
+
resolvedParams
|
|
1544
|
+
);
|
|
1545
|
+
let result = await getResponseValue(response, { req, res });
|
|
1546
|
+
return result;
|
|
1547
|
+
};
|
|
1548
|
+
if (UtilsOs__NS__isElectron) {
|
|
1549
|
+
const ipcKeyName = TaonHelpers__NS__ipcKeyNameRequest(
|
|
1550
|
+
target,
|
|
1551
|
+
methodConfig,
|
|
1552
|
+
expressPath
|
|
1553
|
+
);
|
|
1554
|
+
ipcMain.on(ipcKeyName, async (event, paramsFromBrowser) => {
|
|
1555
|
+
const responseJsonData = await getResult(
|
|
1556
|
+
paramsFromBrowser,
|
|
1557
|
+
void 0,
|
|
1558
|
+
void 0
|
|
1559
|
+
);
|
|
1560
|
+
const sendToIpsMainOn = TaonHelpers__NS__ipcKeyNameResponse(
|
|
1561
|
+
target,
|
|
1562
|
+
methodConfig,
|
|
1563
|
+
expressPath
|
|
1564
|
+
);
|
|
1565
|
+
event.sender.send(sendToIpsMainOn, responseJsonData);
|
|
1566
|
+
});
|
|
1567
|
+
return {
|
|
1568
|
+
expressPath,
|
|
1569
|
+
method: methodConfig.type
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
if (!this.isRemoteHost) {
|
|
1573
|
+
if (UtilsOs__NS__isWebSQL) {
|
|
1574
|
+
if (!this.expressApp[httpMethodType.toLowerCase()]) {
|
|
1575
|
+
this.expressApp[httpMethodType.toLowerCase()] = () => {
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
this.expressApp[httpMethodType.toLowerCase()](
|
|
1580
|
+
expressPath,
|
|
1581
|
+
...middlewareHandlers,
|
|
1582
|
+
async (req, res) => {
|
|
1583
|
+
const args = [];
|
|
1584
|
+
let tBody = req.body;
|
|
1585
|
+
let tParams = req.params;
|
|
1586
|
+
let tQuery = req.query;
|
|
1587
|
+
if (req.headers[Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY]) {
|
|
1588
|
+
try {
|
|
1589
|
+
tBody = JSON.parse(
|
|
1590
|
+
JSON.stringify(tBody),
|
|
1591
|
+
JSON.parse(
|
|
1592
|
+
TaonHelpers__NS__firstStringOrElemFromArray(
|
|
1593
|
+
req.headers[Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY]
|
|
1594
|
+
)
|
|
1595
|
+
)
|
|
1596
|
+
);
|
|
1597
|
+
} catch (e) {
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
if (req.headers[Symbols__NS__old.CIRCURAL_OBJECTS_MAP_QUERY_PARAM]) {
|
|
1601
|
+
try {
|
|
1602
|
+
tQuery = JSON.parse(
|
|
1603
|
+
JSON.stringify(tQuery),
|
|
1604
|
+
JSON.parse(
|
|
1605
|
+
TaonHelpers__NS__firstStringOrElemFromArray(
|
|
1606
|
+
req.headers[Symbols__NS__old.CIRCURAL_OBJECTS_MAP_QUERY_PARAM]
|
|
1607
|
+
)
|
|
1608
|
+
)
|
|
1609
|
+
);
|
|
1610
|
+
} catch (e) {
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
if (req.headers[Symbols__NS__old.MAPPING_CONFIG_HEADER_BODY_PARAMS]) {
|
|
1614
|
+
try {
|
|
1615
|
+
const entity = JSON.parse(
|
|
1616
|
+
TaonHelpers__NS__firstStringOrElemFromArray(
|
|
1617
|
+
req.headers[Symbols__NS__old.MAPPING_CONFIG_HEADER_BODY_PARAMS]
|
|
1618
|
+
)
|
|
1619
|
+
);
|
|
1620
|
+
tBody = Mapping__NS__encode(tBody, entity);
|
|
1621
|
+
} catch (e) {
|
|
1622
|
+
}
|
|
1623
|
+
} else {
|
|
1624
|
+
Object.keys(tBody).forEach((paramName) => {
|
|
1625
|
+
try {
|
|
1626
|
+
const entityForParam = JSON.parse(
|
|
1627
|
+
TaonHelpers__NS__firstStringOrElemFromArray(
|
|
1628
|
+
req.headers[`${Symbols__NS__old.MAPPING_CONFIG_HEADER_BODY_PARAMS}${paramName} `]
|
|
1629
|
+
)
|
|
1630
|
+
);
|
|
1631
|
+
tBody[paramName] = Mapping__NS__encode(
|
|
1632
|
+
tBody[paramName],
|
|
1633
|
+
entityForParam
|
|
1634
|
+
);
|
|
1635
|
+
} catch (e) {
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
if (req.headers[Symbols__NS__old.MAPPING_CONFIG_HEADER_QUERY_PARAMS]) {
|
|
1640
|
+
try {
|
|
1641
|
+
const entity = JSON.parse(
|
|
1642
|
+
TaonHelpers__NS__firstStringOrElemFromArray(
|
|
1643
|
+
req.headers[Symbols__NS__old.MAPPING_CONFIG_HEADER_QUERY_PARAMS]
|
|
1644
|
+
)
|
|
1645
|
+
);
|
|
1646
|
+
tQuery = TaonHelpers__NS__parseJSONwithStringJSONs(
|
|
1647
|
+
Mapping__NS__encode(tQuery, entity)
|
|
1648
|
+
);
|
|
1649
|
+
} catch (e) {
|
|
1650
|
+
}
|
|
1651
|
+
} else {
|
|
1652
|
+
Object.keys(tQuery).forEach((queryParamName) => {
|
|
1653
|
+
try {
|
|
1654
|
+
const entityForParam = JSON.parse(
|
|
1655
|
+
TaonHelpers__NS__firstStringOrElemFromArray(
|
|
1656
|
+
req.headers[`${Symbols__NS__old.MAPPING_CONFIG_HEADER_QUERY_PARAMS}${queryParamName} `]
|
|
1657
|
+
)
|
|
1658
|
+
);
|
|
1659
|
+
let beforeTransofrm = tQuery[queryParamName];
|
|
1660
|
+
if (___NS__isString(beforeTransofrm)) {
|
|
1661
|
+
try {
|
|
1662
|
+
const paresed = TaonHelpers__NS__tryTransformParam(beforeTransofrm);
|
|
1663
|
+
beforeTransofrm = paresed;
|
|
1664
|
+
} catch (e) {
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
const afterEncoding = Mapping__NS__encode(
|
|
1668
|
+
beforeTransofrm,
|
|
1669
|
+
entityForParam
|
|
1670
|
+
);
|
|
1671
|
+
tQuery[queryParamName] = TaonHelpers__NS__parseJSONwithStringJSONs(afterEncoding);
|
|
1672
|
+
} catch (e) {
|
|
1673
|
+
}
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
Object.keys(methodConfig.parameters).forEach((paramName) => {
|
|
1677
|
+
let p = methodConfig.parameters[paramName];
|
|
1678
|
+
if (p.paramType === "Path" && tParams) {
|
|
1679
|
+
args.push(tParams[p.paramName]);
|
|
1680
|
+
}
|
|
1681
|
+
if (p.paramType === "Query" && tQuery) {
|
|
1682
|
+
if (p.paramName) {
|
|
1683
|
+
args.push(tQuery[p.paramName]);
|
|
1684
|
+
} else {
|
|
1685
|
+
args.push(tQuery);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
if (p.paramType === "Header" && req.headers) {
|
|
1689
|
+
args.push(req.headers[p.paramName.toLowerCase()]);
|
|
1690
|
+
}
|
|
1691
|
+
if (p.paramType === "Cookie" && req.cookies) {
|
|
1692
|
+
args.push(req.cookies[p.paramName]);
|
|
1693
|
+
}
|
|
1694
|
+
if (p.paramType === "Body" && tBody) {
|
|
1695
|
+
if (p.paramName && typeof tBody === "object") {
|
|
1696
|
+
args.push(tBody[p.paramName]);
|
|
1697
|
+
} else {
|
|
1698
|
+
args.push(tBody);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
const resolvedParams = args.reverse().map((v) => TaonHelpers__NS__tryTransformParam(v));
|
|
1703
|
+
try {
|
|
1704
|
+
let result = await getResult(resolvedParams, req, res);
|
|
1705
|
+
if (methodConfig.responseType) {
|
|
1706
|
+
if (res.headersSent) {
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
if (methodConfig.overrideExpressSendAsHtml) {
|
|
1711
|
+
res.setHeader("Content-Type", "text/html");
|
|
1712
|
+
res.send(result);
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
if (result instanceof Blob && methodConfig.responseType === "blob") {
|
|
1716
|
+
const blob = result;
|
|
1717
|
+
const file = Buffer.from(await blob.arrayBuffer());
|
|
1718
|
+
res.writeHead(200, {
|
|
1719
|
+
"Content-Type": blob.type,
|
|
1720
|
+
"Content-Length": file.length
|
|
1721
|
+
});
|
|
1722
|
+
res.end(file);
|
|
1723
|
+
} else if (___NS__isString(result) && methodConfig.responseType === "blob") {
|
|
1724
|
+
const img_base64 = result;
|
|
1725
|
+
const m = /^data:(.+?);base64,(.+)$/.exec(img_base64);
|
|
1726
|
+
if (!m) {
|
|
1727
|
+
throw new Error(
|
|
1728
|
+
`[taon - framework] Not a base64 image[${img_base64}]`
|
|
1729
|
+
);
|
|
1730
|
+
}
|
|
1731
|
+
const [_, content_type, file_base64] = m;
|
|
1732
|
+
const file = Buffer.from(file_base64, "base64");
|
|
1733
|
+
res.writeHead(200, {
|
|
1734
|
+
"Content-Type": content_type,
|
|
1735
|
+
"Content-Length": file.length
|
|
1736
|
+
});
|
|
1737
|
+
res.end(file);
|
|
1738
|
+
} else {
|
|
1739
|
+
await EntityProcess.init(result, res);
|
|
1740
|
+
}
|
|
1741
|
+
} catch (error) {
|
|
1742
|
+
if (res.headersSent) {
|
|
1743
|
+
return;
|
|
1744
|
+
}
|
|
1745
|
+
if (methodConfig.overrideExpressSendAsHtml) {
|
|
1746
|
+
res.setHeader("Content-Type", "text/html");
|
|
1747
|
+
res.send(error);
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
this.sendError(res, error, req, expressPath);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
return {
|
|
1756
|
+
expressPath,
|
|
1757
|
+
method: methodConfig.type
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
//#endregion
|
|
1761
|
+
//#region methods & getters / send error
|
|
1762
|
+
sendError(res, error, req, expressPath) {
|
|
1763
|
+
let status = 500;
|
|
1764
|
+
let message = "Internal Server Error";
|
|
1765
|
+
let details = void 0;
|
|
1766
|
+
let success = false;
|
|
1767
|
+
let code = void 0;
|
|
1768
|
+
if (typeof error === "function") {
|
|
1769
|
+
const obj = error(res) || {};
|
|
1770
|
+
status = obj.status || 400;
|
|
1771
|
+
message = obj.message;
|
|
1772
|
+
details = obj.details;
|
|
1773
|
+
code = obj.code;
|
|
1774
|
+
} else if (typeof error === "string") {
|
|
1775
|
+
message = error;
|
|
1776
|
+
status = 400;
|
|
1777
|
+
} else if (error instanceof Error) {
|
|
1778
|
+
message = error.message;
|
|
1779
|
+
details = process.env.NODE_ENV !== "production" ? error.stack : void 0;
|
|
1780
|
+
} else {
|
|
1781
|
+
message = "Unexpected error";
|
|
1782
|
+
details = error;
|
|
1783
|
+
}
|
|
1784
|
+
res.status(status).json({
|
|
1785
|
+
success,
|
|
1786
|
+
message,
|
|
1787
|
+
details,
|
|
1788
|
+
code,
|
|
1789
|
+
[CoreModels__NS__TaonHttpErrorCustomProp]: true
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
//#endregion
|
|
1793
|
+
//#region methods & getters / init client
|
|
1794
|
+
/**
|
|
1795
|
+
* client can be browser or nodejs (when remote host)
|
|
1796
|
+
*/
|
|
1797
|
+
async initClient(target, httpRequestType, methodConfig, expressPath) {
|
|
1798
|
+
const ctx = this;
|
|
1799
|
+
const middlewares = methodConfig.calculatedMiddlewares;
|
|
1800
|
+
const middlewaresInstances = middlewares.map((f) => this.getInstanceBy(f)).filter((f) => ___NS__isFunction(f.interceptClientMethod));
|
|
1801
|
+
middlewaresInstances.forEach((instance) => {
|
|
1802
|
+
const middlewareName = ClassHelpers__NS__getName(instance);
|
|
1803
|
+
const interceptorKey = `${middlewareName}-${methodConfig.type?.toUpperCase()}-${expressPath}`;
|
|
1804
|
+
Resource.request.methodsInterceptors.set(interceptorKey, {
|
|
1805
|
+
intercept: ({ req, next }) => {
|
|
1806
|
+
return instance.interceptClientMethod(
|
|
1807
|
+
{
|
|
1808
|
+
req,
|
|
1809
|
+
next
|
|
1810
|
+
},
|
|
1811
|
+
{
|
|
1812
|
+
methodName: methodConfig.methodName,
|
|
1813
|
+
expressPath,
|
|
1814
|
+
httpRequestType
|
|
1815
|
+
}
|
|
1816
|
+
);
|
|
1817
|
+
}
|
|
1818
|
+
});
|
|
1819
|
+
});
|
|
1820
|
+
const storage = globalThis;
|
|
1821
|
+
const orgMethods = target.prototype[methodConfig.methodName];
|
|
1822
|
+
if (UtilsOs__NS__isElectron) {
|
|
1823
|
+
const ipcRenderer = window.require("electron").ipcRenderer;
|
|
1824
|
+
target.prototype[methodConfig.methodName] = function(...args) {
|
|
1825
|
+
const received = new Promise(async (resolve, reject) => {
|
|
1826
|
+
const headers = {};
|
|
1827
|
+
const { request, response } = TaonHelpers__NS__websqlMocks(headers);
|
|
1828
|
+
});
|
|
1829
|
+
received["observable"] = from(received);
|
|
1830
|
+
return {
|
|
1831
|
+
received,
|
|
1832
|
+
request(axiosConfig) {
|
|
1833
|
+
return received;
|
|
1834
|
+
}
|
|
1835
|
+
};
|
|
1836
|
+
};
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
target.prototype[methodConfig.methodName] = function(...args) {
|
|
1840
|
+
if (!storage[Symbols__NS__old.ENDPOINT_META_CONFIG])
|
|
1841
|
+
storage[Symbols__NS__old.ENDPOINT_META_CONFIG] = {};
|
|
1842
|
+
if (!storage[Symbols__NS__old.ENDPOINT_META_CONFIG][ctx.uriOrigin])
|
|
1843
|
+
storage[Symbols__NS__old.ENDPOINT_META_CONFIG][ctx.uriOrigin] = {};
|
|
1844
|
+
const endpoints = storage[Symbols__NS__old.ENDPOINT_META_CONFIG];
|
|
1845
|
+
let rest;
|
|
1846
|
+
if (!endpoints[ctx.uriOrigin][expressPath]) {
|
|
1847
|
+
let headers = {};
|
|
1848
|
+
if (methodConfig.contentType && !methodConfig.responseType) {
|
|
1849
|
+
rest = Resource.create(
|
|
1850
|
+
ctx.uriOrigin,
|
|
1851
|
+
expressPath,
|
|
1852
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER,
|
|
1853
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY,
|
|
1854
|
+
RestHeaders.from({
|
|
1855
|
+
"Content-Type": methodConfig.contentType,
|
|
1856
|
+
Accept: methodConfig.contentType
|
|
1857
|
+
})
|
|
1858
|
+
);
|
|
1859
|
+
} else if (methodConfig.contentType && methodConfig.responseType) {
|
|
1860
|
+
rest = Resource.create(
|
|
1861
|
+
ctx.uriOrigin,
|
|
1862
|
+
expressPath,
|
|
1863
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER,
|
|
1864
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY,
|
|
1865
|
+
RestHeaders.from({
|
|
1866
|
+
"Content-Type": methodConfig.contentType,
|
|
1867
|
+
Accept: methodConfig.contentType,
|
|
1868
|
+
responsetypeaxios: methodConfig.responseType
|
|
1869
|
+
})
|
|
1870
|
+
);
|
|
1871
|
+
} else if (!methodConfig.contentType && methodConfig.responseType) {
|
|
1872
|
+
rest = Resource.create(
|
|
1873
|
+
ctx.uriOrigin,
|
|
1874
|
+
expressPath,
|
|
1875
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER,
|
|
1876
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY,
|
|
1877
|
+
RestHeaders.from({
|
|
1878
|
+
responsetypeaxios: methodConfig.responseType
|
|
1879
|
+
})
|
|
1880
|
+
);
|
|
1881
|
+
} else {
|
|
1882
|
+
rest = Resource.create(
|
|
1883
|
+
ctx.uriOrigin,
|
|
1884
|
+
expressPath,
|
|
1885
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER,
|
|
1886
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY
|
|
1887
|
+
);
|
|
1888
|
+
}
|
|
1889
|
+
endpoints[ctx.uriOrigin][expressPath] = rest;
|
|
1890
|
+
} else {
|
|
1891
|
+
rest = endpoints[ctx.uriOrigin][expressPath];
|
|
1892
|
+
}
|
|
1893
|
+
const method = httpRequestType.toLowerCase();
|
|
1894
|
+
const pathPrams = {};
|
|
1895
|
+
let queryParams = {};
|
|
1896
|
+
let bodyObject = {};
|
|
1897
|
+
args.forEach((param, i) => {
|
|
1898
|
+
let currentParam = void 0;
|
|
1899
|
+
for (let pp in methodConfig.parameters) {
|
|
1900
|
+
let v = methodConfig.parameters[pp];
|
|
1901
|
+
if (v.index === i) {
|
|
1902
|
+
currentParam = v;
|
|
1903
|
+
break;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
if (!currentParam) {
|
|
1907
|
+
const errorMessage = `[${config.frameworkName}] Unable to resolve parameter at index ${i} for method ${methodConfig.methodName} at path ${expressPath}.`;
|
|
1908
|
+
console.error(errorMessage);
|
|
1909
|
+
process.exit(0);
|
|
1910
|
+
throw new Error(errorMessage);
|
|
1911
|
+
}
|
|
1912
|
+
if (currentParam.paramType === "Path") {
|
|
1913
|
+
pathPrams[currentParam.paramName] = param;
|
|
1914
|
+
}
|
|
1915
|
+
if (currentParam.paramType === "Query") {
|
|
1916
|
+
if (currentParam.paramName) {
|
|
1917
|
+
const mapping = Mapping__NS__decode(param, !ctx.isProductionMode);
|
|
1918
|
+
if (mapping) {
|
|
1919
|
+
rest.headers.set(
|
|
1920
|
+
`${Symbols__NS__old.MAPPING_CONFIG_HEADER_QUERY_PARAMS}${currentParam.paramName} `,
|
|
1921
|
+
JSON.stringify(mapping)
|
|
1922
|
+
);
|
|
1923
|
+
}
|
|
1924
|
+
queryParams[currentParam.paramName] = param;
|
|
1925
|
+
} else {
|
|
1926
|
+
const mapping = Mapping__NS__decode(param, !ctx.isProductionMode);
|
|
1927
|
+
if (mapping) {
|
|
1928
|
+
rest.headers.set(
|
|
1929
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER_QUERY_PARAMS,
|
|
1930
|
+
JSON.stringify(mapping)
|
|
1931
|
+
);
|
|
1932
|
+
}
|
|
1933
|
+
queryParams = ___NS__cloneDeep(param);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
if (currentParam.paramType === "Header") {
|
|
1937
|
+
if (currentParam.paramName) {
|
|
1938
|
+
if (currentParam.paramName === Symbols__NS__old.MDC_KEY) {
|
|
1939
|
+
rest.headers.set(
|
|
1940
|
+
currentParam.paramName,
|
|
1941
|
+
encodeURIComponent(JSON.stringify(param))
|
|
1942
|
+
);
|
|
1943
|
+
} else {
|
|
1944
|
+
rest.headers.set(currentParam.paramName, param);
|
|
1945
|
+
}
|
|
1946
|
+
} else {
|
|
1947
|
+
for (let header in param) {
|
|
1948
|
+
rest.headers.set(header, param[header]);
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
if (currentParam.paramType === "Cookie") {
|
|
1953
|
+
Resource.Cookies.write(
|
|
1954
|
+
currentParam.paramName,
|
|
1955
|
+
param,
|
|
1956
|
+
currentParam.expireInSeconds
|
|
1957
|
+
);
|
|
1958
|
+
}
|
|
1959
|
+
if (currentParam.paramType === "Body") {
|
|
1960
|
+
if (currentParam.paramName) {
|
|
1961
|
+
if (ClassHelpers__NS__getName(bodyObject) === "FormData") {
|
|
1962
|
+
throw new Error(`[taon - framework] Don use param names when posting / putting FormData.
|
|
1963
|
+
Use this:
|
|
1964
|
+
// ...
|
|
1965
|
+
(@Taon.Http.Param.Body() formData: FormData) ...
|
|
1966
|
+
// ...
|
|
1967
|
+
|
|
1968
|
+
instead
|
|
1969
|
+
// ...
|
|
1970
|
+
(@Taon.Http.Param.Body('${currentParam.paramName}') formData: FormData) ...
|
|
1971
|
+
// ...
|
|
1972
|
+
`);
|
|
1973
|
+
}
|
|
1974
|
+
const mapping = Mapping__NS__decode(param, !ctx.isProductionMode);
|
|
1975
|
+
if (mapping) {
|
|
1976
|
+
rest.headers.set(
|
|
1977
|
+
`${Symbols__NS__old.MAPPING_CONFIG_HEADER_BODY_PARAMS}${currentParam.paramName} `,
|
|
1978
|
+
JSON.stringify(mapping)
|
|
1979
|
+
);
|
|
1980
|
+
}
|
|
1981
|
+
bodyObject[currentParam.paramName] = param;
|
|
1982
|
+
} else {
|
|
1983
|
+
const mapping = Mapping__NS__decode(param, !ctx.isProductionMode);
|
|
1984
|
+
if (mapping) {
|
|
1985
|
+
rest.headers.set(
|
|
1986
|
+
Symbols__NS__old.MAPPING_CONFIG_HEADER_BODY_PARAMS,
|
|
1987
|
+
JSON.stringify(mapping)
|
|
1988
|
+
);
|
|
1989
|
+
}
|
|
1990
|
+
bodyObject = param;
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
});
|
|
1994
|
+
if (typeof bodyObject === "object" && ClassHelpers__NS__getName(bodyObject) !== "FormData") {
|
|
1995
|
+
let circuralFromItem = [];
|
|
1996
|
+
bodyObject = JSON10.parse(
|
|
1997
|
+
JSON10.stringify(bodyObject, void 0, void 0, (circs) => {
|
|
1998
|
+
circuralFromItem = circs;
|
|
1999
|
+
})
|
|
2000
|
+
);
|
|
2001
|
+
rest.headers.set(
|
|
2002
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_BODY,
|
|
2003
|
+
JSON10.stringify(circuralFromItem)
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
2006
|
+
if (typeof queryParams === "object") {
|
|
2007
|
+
let circuralFromQueryParams = [];
|
|
2008
|
+
queryParams = JSON10.parse(
|
|
2009
|
+
JSON10.stringify(queryParams, void 0, void 0, (circs) => {
|
|
2010
|
+
circuralFromQueryParams = circs;
|
|
2011
|
+
})
|
|
2012
|
+
);
|
|
2013
|
+
rest.headers.set(
|
|
2014
|
+
Symbols__NS__old.CIRCURAL_OBJECTS_MAP_QUERY_PARAM,
|
|
2015
|
+
JSON10.stringify(circuralFromQueryParams)
|
|
2016
|
+
);
|
|
2017
|
+
}
|
|
2018
|
+
const httpResultObj = {
|
|
2019
|
+
get received() {
|
|
2020
|
+
return rest.model(pathPrams)[method](bodyObject, [queryParams]);
|
|
2021
|
+
},
|
|
2022
|
+
request(axiosConfig) {
|
|
2023
|
+
return rest.model(pathPrams)[method](bodyObject, [queryParams], axiosConfig);
|
|
2024
|
+
}
|
|
2025
|
+
};
|
|
2026
|
+
return httpResultObj;
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
2029
|
+
//#endregion
|
|
2030
|
+
}
|
|
2031
|
+
export {
|
|
2032
|
+
EndpointContext
|
|
2033
|
+
};
|