@nattyjs/common 0.0.1-beta.6 → 0.0.1-beta.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +182 -11
- package/dist/index.d.ts +113 -5
- package/dist/index.mjs +179 -12
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,8 @@ const fs = require('fs');
|
|
|
4
4
|
const dotenv = require('dotenv');
|
|
5
5
|
const dotenvExpand = require('dotenv-expand');
|
|
6
6
|
const path = require('path');
|
|
7
|
+
const child_process = require('child_process');
|
|
8
|
+
const getPortPlease = require('get-port-please');
|
|
7
9
|
|
|
8
10
|
function _interopNamespaceCompat(e) {
|
|
9
11
|
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
@@ -25,6 +27,17 @@ const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
|
25
27
|
const commonContainer = new class {
|
|
26
28
|
constructor() {
|
|
27
29
|
this.metadataConfig = { services: /* @__PURE__ */ new Map() };
|
|
30
|
+
this.types = {};
|
|
31
|
+
}
|
|
32
|
+
registerType(type) {
|
|
33
|
+
if (type) {
|
|
34
|
+
if (typeof type === "string")
|
|
35
|
+
type = JSON.parse(type);
|
|
36
|
+
this.types[type.name] = type;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
setupCliConfig(config) {
|
|
40
|
+
this.nattyCliConfig = config;
|
|
28
41
|
}
|
|
29
42
|
setupConfig(config) {
|
|
30
43
|
const modelBinding = {
|
|
@@ -35,7 +48,8 @@ const commonContainer = new class {
|
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
};
|
|
38
|
-
|
|
51
|
+
const secureConfig = { sensitiveProps: ["password", "mobileNo", "email"] };
|
|
52
|
+
this.nattyConfig = { ...{ api: { rootPath: "api" }, ...{ static: { enabled: true } }, autoGeneratePort: true, modelBinding, globalConfig: {}, secure: secureConfig }, ...config };
|
|
39
53
|
}
|
|
40
54
|
setupBuildOptions(options) {
|
|
41
55
|
this.buildOptions = options;
|
|
@@ -86,6 +100,7 @@ const typeContainer = new class {
|
|
|
86
100
|
this.controllerInfo = /* @__PURE__ */ new Map();
|
|
87
101
|
this.files = /* @__PURE__ */ new Map();
|
|
88
102
|
this.routes = {};
|
|
103
|
+
this.modelSchemas = new Array();
|
|
89
104
|
}
|
|
90
105
|
setControllerJsonSchema(classInfo) {
|
|
91
106
|
const className = this.files.get(classInfo.filePath);
|
|
@@ -107,6 +122,12 @@ const typeContainer = new class {
|
|
|
107
122
|
}
|
|
108
123
|
return controllerName.substr(0, controllerName.length - 10).toLowerCase();
|
|
109
124
|
}
|
|
125
|
+
setClassMetaInfo(typeMeta) {
|
|
126
|
+
this.modelSchemas.push(typeMeta);
|
|
127
|
+
}
|
|
128
|
+
getClassMetaInfo() {
|
|
129
|
+
return this.modelSchemas;
|
|
130
|
+
}
|
|
110
131
|
getRoutes() {
|
|
111
132
|
const routes = {};
|
|
112
133
|
for (const key of this.controllerInfo.keys()) {
|
|
@@ -131,6 +152,7 @@ const typeContainer = new class {
|
|
|
131
152
|
templateInfo[httpMethod][route] = { name: method.name, parameters, returnType: method.returnType };
|
|
132
153
|
}
|
|
133
154
|
routes[templateInfo.route] = templateInfo;
|
|
155
|
+
routes[templateInfo.route].jsDoc = classInfo.jsDoc;
|
|
134
156
|
}
|
|
135
157
|
return routes;
|
|
136
158
|
}
|
|
@@ -225,20 +247,29 @@ function getPath(pathCollection, isIncludeRoot = true, isCreateFolder = false) {
|
|
|
225
247
|
return currentPath;
|
|
226
248
|
}
|
|
227
249
|
|
|
250
|
+
function resolvePath(path$1) {
|
|
251
|
+
return path.resolve(commonContainer.buildOptions.rootDir, path$1);
|
|
252
|
+
}
|
|
253
|
+
|
|
228
254
|
async function readEnv() {
|
|
229
|
-
|
|
255
|
+
const envConfig = commonContainer.nattyCliConfig.env;
|
|
256
|
+
let filePath = envConfig?.dictionary ? void 0 : getPath([ENVIRONMENTS, commonContainer.buildOptions.mode && commonContainer.buildOptions.mode !== "dev" ? `.env.${commonContainer.buildOptions.mode}` : `.env`]);
|
|
257
|
+
if (envConfig && envConfig.path)
|
|
258
|
+
filePath = resolvePath(envConfig.path);
|
|
230
259
|
let parsedEnvTsDefinition = {};
|
|
231
|
-
|
|
260
|
+
let parsedEnv = commonContainer.nattyCliConfig.env?.dictionary;
|
|
261
|
+
if (!parsedEnv && filePath && fs.existsSync(filePath)) {
|
|
232
262
|
const { parsed, error } = dotenv__namespace.config({
|
|
233
263
|
debug: !!process.env.DEBUG || void 0,
|
|
234
264
|
path: filePath
|
|
235
265
|
});
|
|
236
|
-
|
|
237
|
-
parsedEnvTsDefinition = info.parsedEnvTsDefinition;
|
|
238
|
-
commonContainer.setEnvTsDefinition(parsedEnvTsDefinition);
|
|
239
|
-
commonContainer.setEnvValueInfo(info.envVariableValueInfo);
|
|
240
|
-
dotenvExpand__namespace.expand({ parsed });
|
|
266
|
+
parsedEnv = parsed;
|
|
241
267
|
}
|
|
268
|
+
const info = getEnvTsDefinition(parsedEnv);
|
|
269
|
+
parsedEnvTsDefinition = info.parsedEnvTsDefinition;
|
|
270
|
+
commonContainer.setEnvTsDefinition(parsedEnvTsDefinition);
|
|
271
|
+
commonContainer.setEnvValueInfo(info.envVariableValueInfo);
|
|
272
|
+
dotenvExpand__namespace.expand({ parsed: parsedEnv });
|
|
242
273
|
return parsedEnvTsDefinition;
|
|
243
274
|
}
|
|
244
275
|
|
|
@@ -286,10 +317,10 @@ function readEnvKey(key) {
|
|
|
286
317
|
}
|
|
287
318
|
|
|
288
319
|
class UserIdentity {
|
|
289
|
-
constructor(isAuthenticate, id,
|
|
320
|
+
constructor(isAuthenticate, id, claims) {
|
|
290
321
|
this.isAuthenticate = isAuthenticate;
|
|
291
322
|
this.id = id;
|
|
292
|
-
this.
|
|
323
|
+
this.claims = claims;
|
|
293
324
|
}
|
|
294
325
|
}
|
|
295
326
|
|
|
@@ -381,7 +412,7 @@ class List {
|
|
|
381
412
|
if (this.count()) {
|
|
382
413
|
return predicate ? this.where(predicate).first() : this._entities[0];
|
|
383
414
|
} else {
|
|
384
|
-
|
|
415
|
+
return void 0;
|
|
385
416
|
}
|
|
386
417
|
}
|
|
387
418
|
firstOrDefault(predicate) {
|
|
@@ -575,13 +606,150 @@ var FrameworkType = /* @__PURE__ */ ((FrameworkType2) => {
|
|
|
575
606
|
return FrameworkType2;
|
|
576
607
|
})(FrameworkType || {});
|
|
577
608
|
|
|
609
|
+
function registerType(type) {
|
|
610
|
+
commonContainer.registerType(type);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
class AbstractRunner {
|
|
614
|
+
async stop() {
|
|
615
|
+
if (this.childProcess)
|
|
616
|
+
this.childProcess.kill();
|
|
617
|
+
}
|
|
618
|
+
async exec(command, args, cwd = process.cwd()) {
|
|
619
|
+
const options = {
|
|
620
|
+
cwd,
|
|
621
|
+
stdio: "pipe",
|
|
622
|
+
shell: true
|
|
623
|
+
};
|
|
624
|
+
return new Promise((resolve, reject) => {
|
|
625
|
+
const child = child_process.spawn(
|
|
626
|
+
`${command}`,
|
|
627
|
+
[...args],
|
|
628
|
+
options
|
|
629
|
+
);
|
|
630
|
+
this.childProcess = child;
|
|
631
|
+
child.stdout.on(
|
|
632
|
+
"data",
|
|
633
|
+
(data) => {
|
|
634
|
+
const writeData = data.toString().replace(/\r\n|\n/, "");
|
|
635
|
+
if (writeData.indexOf("[NATTYJS]") > -1 || writeData.indexOf("[NATTYJS:LOGGER]") > -1) {
|
|
636
|
+
console.log(writeData);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
child.stderr.on("data", (data) => {
|
|
641
|
+
const writeData = data.toString().replace(/\r\n|\n/, "");
|
|
642
|
+
console.log(writeData);
|
|
643
|
+
});
|
|
644
|
+
child.on("close", (code) => {
|
|
645
|
+
if (code === 0) {
|
|
646
|
+
resolve(null);
|
|
647
|
+
} else {
|
|
648
|
+
console.error(
|
|
649
|
+
`${command} ${args}`
|
|
650
|
+
);
|
|
651
|
+
reject();
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
async function getPort() {
|
|
659
|
+
const portNumber = commonContainer.nattyConfig?.port || 3200;
|
|
660
|
+
if (portNumber)
|
|
661
|
+
return portNumber;
|
|
662
|
+
const port = await getPortPlease.getPort({ ports: [portNumber, ...Array(50).fill(3001).map((fillValue, index) => fillValue + index)] });
|
|
663
|
+
commonContainer.nattyConfig.port = port;
|
|
664
|
+
return port;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const reset = "\x1B[0m";
|
|
668
|
+
const NATTY_LOGGER = `[NATTYJS:LOGGER] `;
|
|
669
|
+
const log = {
|
|
670
|
+
green: (text) => console.log("\x1B[32m" + NATTY_LOGGER + text + reset),
|
|
671
|
+
red: (text) => console.log("\x1B[31m" + NATTY_LOGGER + text + reset),
|
|
672
|
+
blue: (text) => console.log("\x1B[34m" + NATTY_LOGGER + text + reset),
|
|
673
|
+
yellow: (text) => console.log("\x1B[33m" + NATTY_LOGGER + text + reset)
|
|
674
|
+
};
|
|
675
|
+
class AbstractConsoleLogger {
|
|
676
|
+
log(message) {
|
|
677
|
+
log.yellow(message);
|
|
678
|
+
}
|
|
679
|
+
info(message) {
|
|
680
|
+
log.blue(message);
|
|
681
|
+
}
|
|
682
|
+
warn(message) {
|
|
683
|
+
log.yellow(message);
|
|
684
|
+
}
|
|
685
|
+
error(message) {
|
|
686
|
+
log.red(message);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
class ConsoleLogger extends AbstractConsoleLogger {
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function typed() {
|
|
694
|
+
return function(OriginalClass) {
|
|
695
|
+
const extendedClass = class extends OriginalClass {
|
|
696
|
+
constructor(...args) {
|
|
697
|
+
super(...args);
|
|
698
|
+
const typeInfo = commonContainer.types[OriginalClass.name];
|
|
699
|
+
defineProps(this, typeInfo?.props, OriginalClass.name);
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
delete extendedClass.name;
|
|
703
|
+
Object.defineProperty(extendedClass, "name", {
|
|
704
|
+
value: OriginalClass.name,
|
|
705
|
+
writable: false
|
|
706
|
+
});
|
|
707
|
+
return extendedClass;
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
const types = ["string", "number", "boolean"];
|
|
711
|
+
function defineProps(instance, props, modelName) {
|
|
712
|
+
if (props && Array.isArray(props)) {
|
|
713
|
+
for (const prop of props) {
|
|
714
|
+
if (prop.type && types.indexOf(prop.type) > -1) {
|
|
715
|
+
overrideProp(instance, prop, modelName);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function overrideProp(instance, prop, modelName) {
|
|
721
|
+
let descriptor = Object.getOwnPropertyDescriptor(
|
|
722
|
+
Object.getPrototypeOf(instance),
|
|
723
|
+
prop.name
|
|
724
|
+
);
|
|
725
|
+
let value = instance[prop.name];
|
|
726
|
+
Object.defineProperty(instance, prop.name, {
|
|
727
|
+
enumerable: true,
|
|
728
|
+
configurable: true,
|
|
729
|
+
get: () => {
|
|
730
|
+
return descriptor ? descriptor.get.call(instance) : value;
|
|
731
|
+
},
|
|
732
|
+
set: (v) => {
|
|
733
|
+
if (prop.type == "boolean" && v !== null && v !== void 0)
|
|
734
|
+
v = v === 0 || v === false ? false : true;
|
|
735
|
+
const type = typeof v;
|
|
736
|
+
if (v === null || v === void 0 || prop.type == type)
|
|
737
|
+
value = v;
|
|
738
|
+
else
|
|
739
|
+
throw new Error(`Incorrect value type of ${modelName} class property '${prop.name}' `);
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
|
|
578
744
|
exports.ALLOW_METHODS = ALLOW_METHODS;
|
|
745
|
+
exports.AbstractRunner = AbstractRunner;
|
|
579
746
|
exports.ActionFilter = ActionFilter;
|
|
580
747
|
exports.AuthenticationFilter = AuthenticationFilter;
|
|
581
748
|
exports.AuthorizationFilter = AuthorizationFilter;
|
|
582
749
|
exports.BACK_SLASH_REGEX = BACK_SLASH_REGEX;
|
|
583
750
|
exports.BLANK = BLANK;
|
|
584
751
|
exports.CONTROLLER = CONTROLLER;
|
|
752
|
+
exports.ConsoleLogger = ConsoleLogger;
|
|
585
753
|
exports.DEFAULT_ACTIONS = DEFAULT_ACTIONS;
|
|
586
754
|
exports.DEFAULT_CHILD_PATH = DEFAULT_CHILD_PATH;
|
|
587
755
|
exports.DELETE = DELETE;
|
|
@@ -606,10 +774,13 @@ exports.commonContainer = commonContainer;
|
|
|
606
774
|
exports.createPath = createPath;
|
|
607
775
|
exports.createTestServer = createTestServer;
|
|
608
776
|
exports.getPath = getPath;
|
|
777
|
+
exports.getPort = getPort;
|
|
609
778
|
exports.isConstructor = isConstructor;
|
|
610
779
|
exports.isEqual = isEqual;
|
|
611
780
|
exports.isFunction = isFunction;
|
|
612
781
|
exports.isObject = isObject;
|
|
613
782
|
exports.readEnv = readEnv;
|
|
614
783
|
exports.readEnvKey = readEnvKey;
|
|
784
|
+
exports.registerType = registerType;
|
|
615
785
|
exports.typeContainer = typeContainer;
|
|
786
|
+
exports.typed = typed;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { RequestRouteInfo, IHttpResult, IModelBindingContext, ProblemDetail, IExceptionContext, HttpResponseInit, NattyTestModule, ModelBinding, BuildOptions, ClassTypeInfo } from '@nattyjs/types';
|
|
1
|
+
import { RequestRouteInfo, IHttpResult, Cookie, IModelBindingContext, ProblemDetail, IExceptionContext, HttpResponseInit, NattyTestModule, ModelBinding, GenerateOpenApiOptions, BuildOptions, TypesInfo, ClassTypeInfo, TypeMeta } from '@nattyjs/types';
|
|
2
|
+
import { ChildProcess } from 'child_process';
|
|
2
3
|
|
|
3
4
|
interface ClassType<T> extends Function {
|
|
4
5
|
new (...args: any[]): T;
|
|
@@ -7,8 +8,8 @@ interface ClassType<T> extends Function {
|
|
|
7
8
|
declare class UserIdentity<T> {
|
|
8
9
|
isAuthenticate: boolean;
|
|
9
10
|
id?: any;
|
|
10
|
-
|
|
11
|
-
constructor(isAuthenticate: boolean, id?: any,
|
|
11
|
+
claims?: T;
|
|
12
|
+
constructor(isAuthenticate: boolean, id?: any, claims?: T);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
interface IExecutionContext {
|
|
@@ -21,6 +22,11 @@ interface IExecutionContext {
|
|
|
21
22
|
|
|
22
23
|
interface IActionExecutedContext extends IExecutionContext {
|
|
23
24
|
content: any;
|
|
25
|
+
get response(): {
|
|
26
|
+
cookies: Array<Cookie>;
|
|
27
|
+
headers: Headers;
|
|
28
|
+
status: number;
|
|
29
|
+
};
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
interface IActionExecutingContext extends IExecutionContext {
|
|
@@ -37,8 +43,12 @@ declare abstract class AuthenticationFilter {
|
|
|
37
43
|
onFailedResponse(): ProblemDetail;
|
|
38
44
|
}
|
|
39
45
|
|
|
46
|
+
interface IAuthorizationContext extends IActionExecutingContext {
|
|
47
|
+
config: any;
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
declare abstract class AuthorizationFilter {
|
|
41
|
-
abstract onAuthorization(httpContext:
|
|
51
|
+
abstract onAuthorization(httpContext: IAuthorizationContext): Promise<boolean>;
|
|
42
52
|
onFailedAuthorization(): ProblemDetail;
|
|
43
53
|
}
|
|
44
54
|
|
|
@@ -53,6 +63,36 @@ interface GlobalConfig {
|
|
|
53
63
|
onException?: ClassType<ExceptionFilter>;
|
|
54
64
|
}
|
|
55
65
|
|
|
66
|
+
interface CorsConfig {
|
|
67
|
+
origin: string[];
|
|
68
|
+
methods: string;
|
|
69
|
+
preflightContinue: boolean;
|
|
70
|
+
optionsSuccessStatus: number;
|
|
71
|
+
credentials: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface PayloadConfig {
|
|
75
|
+
limit?: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface SecureConfig {
|
|
79
|
+
sensitiveProps?: String[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface PreInitEventConfig {
|
|
83
|
+
cors?: CorsConfig;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface LifeCycleEvents {
|
|
87
|
+
preInit: () => PreInitEventConfig;
|
|
88
|
+
onStart: () => Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface WebScheduleConfig {
|
|
92
|
+
interval: number;
|
|
93
|
+
scheduleFunction: () => Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
|
|
56
96
|
interface NattyConfig {
|
|
57
97
|
app: any;
|
|
58
98
|
testModule?: NattyTestModule;
|
|
@@ -62,12 +102,58 @@ interface NattyConfig {
|
|
|
62
102
|
modelBinding?: ModelBinding;
|
|
63
103
|
global?: GlobalConfig;
|
|
64
104
|
autoGeneratePort?: boolean;
|
|
105
|
+
port?: number;
|
|
106
|
+
cors?: CorsConfig;
|
|
107
|
+
payload?: PayloadConfig;
|
|
108
|
+
secure?: SecureConfig;
|
|
109
|
+
lifeCycle?: LifeCycleEvents;
|
|
110
|
+
webSchedules?: Array<WebScheduleConfig>;
|
|
111
|
+
static?: {
|
|
112
|
+
indexFile?: string;
|
|
113
|
+
spaFallback?: boolean;
|
|
114
|
+
enabled?: boolean;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
declare abstract class AbstractRunner {
|
|
119
|
+
abstract run(): void;
|
|
120
|
+
childProcess: ChildProcess;
|
|
121
|
+
stop(): Promise<void>;
|
|
122
|
+
protected exec(command: string, args: any[], cwd?: string): Promise<null | string>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
interface EnvConfig {
|
|
126
|
+
path: string;
|
|
127
|
+
dictionary: {
|
|
128
|
+
[key: string]: any;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
interface PackageJsonConfig {
|
|
133
|
+
addExports: string[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface LibraryConfig {
|
|
137
|
+
packageJson: PackageJsonConfig;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface NattyCliConfig {
|
|
141
|
+
library?: Partial<LibraryConfig>;
|
|
142
|
+
env?: Partial<EnvConfig>;
|
|
143
|
+
runner?: ClassType<AbstractRunner>;
|
|
144
|
+
port?: number;
|
|
145
|
+
openapi?: GenerateOpenApiOptions;
|
|
146
|
+
swagger?: {
|
|
147
|
+
ui: boolean;
|
|
148
|
+
};
|
|
65
149
|
}
|
|
66
150
|
|
|
67
151
|
declare const commonContainer: {
|
|
68
152
|
setupConfig(config?: NattyConfig): void;
|
|
153
|
+
setupCliConfig(config: NattyCliConfig): void;
|
|
69
154
|
setupBuildOptions(options: BuildOptions): any;
|
|
70
155
|
get nattyConfig(): NattyConfig;
|
|
156
|
+
get nattyCliConfig(): NattyCliConfig;
|
|
71
157
|
get buildOptions(): BuildOptions;
|
|
72
158
|
get envTsDefinition(): {
|
|
73
159
|
[key: string]: string;
|
|
@@ -84,11 +170,15 @@ declare const commonContainer: {
|
|
|
84
170
|
setMetadata(key: string, value: any, propName: string): void;
|
|
85
171
|
getMetadataValue(key: string, propName: string): any;
|
|
86
172
|
get globalConfig(): GlobalConfig;
|
|
173
|
+
registerType(type: TypesInfo): void;
|
|
174
|
+
types: TypesInfo;
|
|
87
175
|
};
|
|
88
176
|
|
|
89
177
|
declare const typeContainer: {
|
|
90
178
|
setControllerJsonSchema(classInfo: ClassTypeInfo): void;
|
|
91
179
|
getControllersJsonSchema(): ClassTypeInfo[];
|
|
180
|
+
setClassMetaInfo(typeMeta: TypeMeta): void;
|
|
181
|
+
getClassMetaInfo(): TypeMeta[];
|
|
92
182
|
getRoutes(): any;
|
|
93
183
|
getControllerJsonSchema(name: string): ClassTypeInfo;
|
|
94
184
|
removeControllerInfo(path: string): void;
|
|
@@ -219,4 +309,22 @@ interface NattyAppConfig extends NattyConfig {
|
|
|
219
309
|
framework: FrameworkType;
|
|
220
310
|
}
|
|
221
311
|
|
|
222
|
-
|
|
312
|
+
declare function registerType(type: TypesInfo): void;
|
|
313
|
+
|
|
314
|
+
declare function getPort(): Promise<number>;
|
|
315
|
+
|
|
316
|
+
declare abstract class AbstractConsoleLogger {
|
|
317
|
+
log(message: any): void;
|
|
318
|
+
info(message: any): void;
|
|
319
|
+
warn(message: any): void;
|
|
320
|
+
error(message: any): void;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
declare class ConsoleLogger extends AbstractConsoleLogger {
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
declare function typed(): <T extends {
|
|
327
|
+
new (...args: any[]): {};
|
|
328
|
+
}>(OriginalClass: T) => T;
|
|
329
|
+
|
|
330
|
+
export { ALLOW_METHODS, AbstractRunner, ActionFilter, AuthenticationFilter, AuthorizationFilter, BACK_SLASH_REGEX, BLANK, CONTROLLER, Claim, ClassType, ConsoleLogger, DEFAULT_ACTIONS, DEFAULT_CHILD_PATH, DELETE, ENVIRONMENTS, ExceptionFilter, FrameworkType, GET, GlobalConfig, HTTP_METHOD_ROUTES, IActionExecutedContext, IActionExecutingContext, IAuthorizationContext, IExecutionContext, IGNORE_METHODS, List, MetaConfigProps, Middleware, NattyAppConfig, NattyCliConfig, NattyConfig, POST, PUT, RIGHT_SLASH, ROUTE_INSTANCES, ROUTE_METHODS, ROUTE_PATHS, TS_EXTENSION, UserIdentity, WebScheduleConfig, commonContainer, createPath, createTestServer, getPath, getPort, isConstructor, isEqual, isFunction, isObject, readEnv, readEnvKey, registerType, typeContainer, typed };
|
package/dist/index.mjs
CHANGED
|
@@ -3,10 +3,24 @@ import { existsSync } from 'fs';
|
|
|
3
3
|
import * as dotenv from 'dotenv';
|
|
4
4
|
import * as dotenvExpand from 'dotenv-expand';
|
|
5
5
|
import * as path from 'path';
|
|
6
|
+
import { resolve } from 'path';
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
import { getPort as getPort$1 } from 'get-port-please';
|
|
6
9
|
|
|
7
10
|
const commonContainer = new class {
|
|
8
11
|
constructor() {
|
|
9
12
|
this.metadataConfig = { services: /* @__PURE__ */ new Map() };
|
|
13
|
+
this.types = {};
|
|
14
|
+
}
|
|
15
|
+
registerType(type) {
|
|
16
|
+
if (type) {
|
|
17
|
+
if (typeof type === "string")
|
|
18
|
+
type = JSON.parse(type);
|
|
19
|
+
this.types[type.name] = type;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
setupCliConfig(config) {
|
|
23
|
+
this.nattyCliConfig = config;
|
|
10
24
|
}
|
|
11
25
|
setupConfig(config) {
|
|
12
26
|
const modelBinding = {
|
|
@@ -17,7 +31,8 @@ const commonContainer = new class {
|
|
|
17
31
|
}
|
|
18
32
|
}
|
|
19
33
|
};
|
|
20
|
-
|
|
34
|
+
const secureConfig = { sensitiveProps: ["password", "mobileNo", "email"] };
|
|
35
|
+
this.nattyConfig = { ...{ api: { rootPath: "api" }, ...{ static: { enabled: true } }, autoGeneratePort: true, modelBinding, globalConfig: {}, secure: secureConfig }, ...config };
|
|
21
36
|
}
|
|
22
37
|
setupBuildOptions(options) {
|
|
23
38
|
this.buildOptions = options;
|
|
@@ -68,6 +83,7 @@ const typeContainer = new class {
|
|
|
68
83
|
this.controllerInfo = /* @__PURE__ */ new Map();
|
|
69
84
|
this.files = /* @__PURE__ */ new Map();
|
|
70
85
|
this.routes = {};
|
|
86
|
+
this.modelSchemas = new Array();
|
|
71
87
|
}
|
|
72
88
|
setControllerJsonSchema(classInfo) {
|
|
73
89
|
const className = this.files.get(classInfo.filePath);
|
|
@@ -89,6 +105,12 @@ const typeContainer = new class {
|
|
|
89
105
|
}
|
|
90
106
|
return controllerName.substr(0, controllerName.length - 10).toLowerCase();
|
|
91
107
|
}
|
|
108
|
+
setClassMetaInfo(typeMeta) {
|
|
109
|
+
this.modelSchemas.push(typeMeta);
|
|
110
|
+
}
|
|
111
|
+
getClassMetaInfo() {
|
|
112
|
+
return this.modelSchemas;
|
|
113
|
+
}
|
|
92
114
|
getRoutes() {
|
|
93
115
|
const routes = {};
|
|
94
116
|
for (const key of this.controllerInfo.keys()) {
|
|
@@ -113,6 +135,7 @@ const typeContainer = new class {
|
|
|
113
135
|
templateInfo[httpMethod][route] = { name: method.name, parameters, returnType: method.returnType };
|
|
114
136
|
}
|
|
115
137
|
routes[templateInfo.route] = templateInfo;
|
|
138
|
+
routes[templateInfo.route].jsDoc = classInfo.jsDoc;
|
|
116
139
|
}
|
|
117
140
|
return routes;
|
|
118
141
|
}
|
|
@@ -207,20 +230,29 @@ function getPath(pathCollection, isIncludeRoot = true, isCreateFolder = false) {
|
|
|
207
230
|
return currentPath;
|
|
208
231
|
}
|
|
209
232
|
|
|
233
|
+
function resolvePath(path) {
|
|
234
|
+
return resolve(commonContainer.buildOptions.rootDir, path);
|
|
235
|
+
}
|
|
236
|
+
|
|
210
237
|
async function readEnv() {
|
|
211
|
-
|
|
238
|
+
const envConfig = commonContainer.nattyCliConfig.env;
|
|
239
|
+
let filePath = envConfig?.dictionary ? void 0 : getPath([ENVIRONMENTS, commonContainer.buildOptions.mode && commonContainer.buildOptions.mode !== "dev" ? `.env.${commonContainer.buildOptions.mode}` : `.env`]);
|
|
240
|
+
if (envConfig && envConfig.path)
|
|
241
|
+
filePath = resolvePath(envConfig.path);
|
|
212
242
|
let parsedEnvTsDefinition = {};
|
|
213
|
-
|
|
243
|
+
let parsedEnv = commonContainer.nattyCliConfig.env?.dictionary;
|
|
244
|
+
if (!parsedEnv && filePath && existsSync(filePath)) {
|
|
214
245
|
const { parsed, error } = dotenv.config({
|
|
215
246
|
debug: !!process.env.DEBUG || void 0,
|
|
216
247
|
path: filePath
|
|
217
248
|
});
|
|
218
|
-
|
|
219
|
-
parsedEnvTsDefinition = info.parsedEnvTsDefinition;
|
|
220
|
-
commonContainer.setEnvTsDefinition(parsedEnvTsDefinition);
|
|
221
|
-
commonContainer.setEnvValueInfo(info.envVariableValueInfo);
|
|
222
|
-
dotenvExpand.expand({ parsed });
|
|
249
|
+
parsedEnv = parsed;
|
|
223
250
|
}
|
|
251
|
+
const info = getEnvTsDefinition(parsedEnv);
|
|
252
|
+
parsedEnvTsDefinition = info.parsedEnvTsDefinition;
|
|
253
|
+
commonContainer.setEnvTsDefinition(parsedEnvTsDefinition);
|
|
254
|
+
commonContainer.setEnvValueInfo(info.envVariableValueInfo);
|
|
255
|
+
dotenvExpand.expand({ parsed: parsedEnv });
|
|
224
256
|
return parsedEnvTsDefinition;
|
|
225
257
|
}
|
|
226
258
|
|
|
@@ -268,10 +300,10 @@ function readEnvKey(key) {
|
|
|
268
300
|
}
|
|
269
301
|
|
|
270
302
|
class UserIdentity {
|
|
271
|
-
constructor(isAuthenticate, id,
|
|
303
|
+
constructor(isAuthenticate, id, claims) {
|
|
272
304
|
this.isAuthenticate = isAuthenticate;
|
|
273
305
|
this.id = id;
|
|
274
|
-
this.
|
|
306
|
+
this.claims = claims;
|
|
275
307
|
}
|
|
276
308
|
}
|
|
277
309
|
|
|
@@ -363,7 +395,7 @@ class List {
|
|
|
363
395
|
if (this.count()) {
|
|
364
396
|
return predicate ? this.where(predicate).first() : this._entities[0];
|
|
365
397
|
} else {
|
|
366
|
-
|
|
398
|
+
return void 0;
|
|
367
399
|
}
|
|
368
400
|
}
|
|
369
401
|
firstOrDefault(predicate) {
|
|
@@ -557,4 +589,139 @@ var FrameworkType = /* @__PURE__ */ ((FrameworkType2) => {
|
|
|
557
589
|
return FrameworkType2;
|
|
558
590
|
})(FrameworkType || {});
|
|
559
591
|
|
|
560
|
-
|
|
592
|
+
function registerType(type) {
|
|
593
|
+
commonContainer.registerType(type);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
class AbstractRunner {
|
|
597
|
+
async stop() {
|
|
598
|
+
if (this.childProcess)
|
|
599
|
+
this.childProcess.kill();
|
|
600
|
+
}
|
|
601
|
+
async exec(command, args, cwd = process.cwd()) {
|
|
602
|
+
const options = {
|
|
603
|
+
cwd,
|
|
604
|
+
stdio: "pipe",
|
|
605
|
+
shell: true
|
|
606
|
+
};
|
|
607
|
+
return new Promise((resolve, reject) => {
|
|
608
|
+
const child = spawn(
|
|
609
|
+
`${command}`,
|
|
610
|
+
[...args],
|
|
611
|
+
options
|
|
612
|
+
);
|
|
613
|
+
this.childProcess = child;
|
|
614
|
+
child.stdout.on(
|
|
615
|
+
"data",
|
|
616
|
+
(data) => {
|
|
617
|
+
const writeData = data.toString().replace(/\r\n|\n/, "");
|
|
618
|
+
if (writeData.indexOf("[NATTYJS]") > -1 || writeData.indexOf("[NATTYJS:LOGGER]") > -1) {
|
|
619
|
+
console.log(writeData);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
);
|
|
623
|
+
child.stderr.on("data", (data) => {
|
|
624
|
+
const writeData = data.toString().replace(/\r\n|\n/, "");
|
|
625
|
+
console.log(writeData);
|
|
626
|
+
});
|
|
627
|
+
child.on("close", (code) => {
|
|
628
|
+
if (code === 0) {
|
|
629
|
+
resolve(null);
|
|
630
|
+
} else {
|
|
631
|
+
console.error(
|
|
632
|
+
`${command} ${args}`
|
|
633
|
+
);
|
|
634
|
+
reject();
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
async function getPort() {
|
|
642
|
+
const portNumber = commonContainer.nattyConfig?.port || 3200;
|
|
643
|
+
if (portNumber)
|
|
644
|
+
return portNumber;
|
|
645
|
+
const port = await getPort$1({ ports: [portNumber, ...Array(50).fill(3001).map((fillValue, index) => fillValue + index)] });
|
|
646
|
+
commonContainer.nattyConfig.port = port;
|
|
647
|
+
return port;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const reset = "\x1B[0m";
|
|
651
|
+
const NATTY_LOGGER = `[NATTYJS:LOGGER] `;
|
|
652
|
+
const log = {
|
|
653
|
+
green: (text) => console.log("\x1B[32m" + NATTY_LOGGER + text + reset),
|
|
654
|
+
red: (text) => console.log("\x1B[31m" + NATTY_LOGGER + text + reset),
|
|
655
|
+
blue: (text) => console.log("\x1B[34m" + NATTY_LOGGER + text + reset),
|
|
656
|
+
yellow: (text) => console.log("\x1B[33m" + NATTY_LOGGER + text + reset)
|
|
657
|
+
};
|
|
658
|
+
class AbstractConsoleLogger {
|
|
659
|
+
log(message) {
|
|
660
|
+
log.yellow(message);
|
|
661
|
+
}
|
|
662
|
+
info(message) {
|
|
663
|
+
log.blue(message);
|
|
664
|
+
}
|
|
665
|
+
warn(message) {
|
|
666
|
+
log.yellow(message);
|
|
667
|
+
}
|
|
668
|
+
error(message) {
|
|
669
|
+
log.red(message);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
class ConsoleLogger extends AbstractConsoleLogger {
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function typed() {
|
|
677
|
+
return function(OriginalClass) {
|
|
678
|
+
const extendedClass = class extends OriginalClass {
|
|
679
|
+
constructor(...args) {
|
|
680
|
+
super(...args);
|
|
681
|
+
const typeInfo = commonContainer.types[OriginalClass.name];
|
|
682
|
+
defineProps(this, typeInfo?.props, OriginalClass.name);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
delete extendedClass.name;
|
|
686
|
+
Object.defineProperty(extendedClass, "name", {
|
|
687
|
+
value: OriginalClass.name,
|
|
688
|
+
writable: false
|
|
689
|
+
});
|
|
690
|
+
return extendedClass;
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
const types = ["string", "number", "boolean"];
|
|
694
|
+
function defineProps(instance, props, modelName) {
|
|
695
|
+
if (props && Array.isArray(props)) {
|
|
696
|
+
for (const prop of props) {
|
|
697
|
+
if (prop.type && types.indexOf(prop.type) > -1) {
|
|
698
|
+
overrideProp(instance, prop, modelName);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
function overrideProp(instance, prop, modelName) {
|
|
704
|
+
let descriptor = Object.getOwnPropertyDescriptor(
|
|
705
|
+
Object.getPrototypeOf(instance),
|
|
706
|
+
prop.name
|
|
707
|
+
);
|
|
708
|
+
let value = instance[prop.name];
|
|
709
|
+
Object.defineProperty(instance, prop.name, {
|
|
710
|
+
enumerable: true,
|
|
711
|
+
configurable: true,
|
|
712
|
+
get: () => {
|
|
713
|
+
return descriptor ? descriptor.get.call(instance) : value;
|
|
714
|
+
},
|
|
715
|
+
set: (v) => {
|
|
716
|
+
if (prop.type == "boolean" && v !== null && v !== void 0)
|
|
717
|
+
v = v === 0 || v === false ? false : true;
|
|
718
|
+
const type = typeof v;
|
|
719
|
+
if (v === null || v === void 0 || prop.type == type)
|
|
720
|
+
value = v;
|
|
721
|
+
else
|
|
722
|
+
throw new Error(`Incorrect value type of ${modelName} class property '${prop.name}' `);
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
export { ALLOW_METHODS, AbstractRunner, ActionFilter, AuthenticationFilter, AuthorizationFilter, BACK_SLASH_REGEX, BLANK, CONTROLLER, ConsoleLogger, DEFAULT_ACTIONS, DEFAULT_CHILD_PATH, DELETE, ENVIRONMENTS, ExceptionFilter, FrameworkType, GET, HTTP_METHOD_ROUTES, IGNORE_METHODS, List, MetaConfigProps, Middleware, POST, PUT, RIGHT_SLASH, ROUTE_INSTANCES, ROUTE_METHODS, ROUTE_PATHS, TS_EXTENSION, UserIdentity, commonContainer, createPath, createTestServer, getPath, getPort, isConstructor, isEqual, isFunction, isObject, readEnv, readEnvKey, registerType, typeContainer, typed };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nattyjs/common",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.61",
|
|
4
4
|
"description": "Now I’m the model of a modern major general / The venerated Virginian veteran whose men are all / Lining up, to put me up on a pedestal / Writin’ letters to relatives / Embellishin’ my elegance and eloquence / But the elephant is in the room / The truth is in ya face when ya hear the British cannons go / BOOM",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "ajayojha <ojhaajay@outlook.com>",
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"dotenv": "16.3.1",
|
|
19
|
-
"dotenv-expand": "10.0.0"
|
|
19
|
+
"dotenv-expand": "10.0.0",
|
|
20
|
+
"get-port-please": "3.1.1"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@types/node": "20.3.1",
|
|
23
|
-
"@nattyjs/types": "0.0.1-beta.
|
|
24
|
+
"@nattyjs/types": "0.0.1-beta.61",
|
|
24
25
|
"unbuild": "1.2.1"
|
|
25
26
|
}
|
|
26
27
|
}
|