nural 0.3.7 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
4
4
  import { z } from 'zod';
5
5
  export { z } from 'zod';
6
6
  import express from 'express';
7
+ import http from 'http';
7
8
  import Fastify from 'fastify';
8
9
 
9
10
  // src/core/exceptions.ts
@@ -233,10 +234,11 @@ var ExpressAdapter = class {
233
234
  constructor(errorConfig) {
234
235
  this.app = express();
235
236
  this.app.use(express.json());
237
+ this.server = http.createServer(this.app);
236
238
  this.errorConfig = errorConfig ?? DEFAULT_ERROR_HANDLER_CONFIG;
237
239
  }
238
240
  listen(port, cb) {
239
- this.app.listen(port, cb);
241
+ return this.server.listen(port, cb);
240
242
  }
241
243
  use(middleware) {
242
244
  this.app.use(middleware);
@@ -355,6 +357,9 @@ var ExpressAdapter = class {
355
357
  }
356
358
  };
357
359
  var FastifyAdapter = class {
360
+ get server() {
361
+ return this.app.server;
362
+ }
358
363
  constructor(errorConfig) {
359
364
  this.app = Fastify();
360
365
  this.errorConfig = errorConfig ?? DEFAULT_ERROR_HANDLER_CONFIG;
@@ -367,6 +372,7 @@ var FastifyAdapter = class {
367
372
  }
368
373
  if (cb) cb();
369
374
  });
375
+ return this.app.server;
370
376
  }
371
377
  use(middleware) {
372
378
  if (typeof middleware === "function") {
@@ -480,118 +486,6 @@ var FastifyAdapter = class {
480
486
  });
481
487
  }
482
488
  };
483
-
484
- // src/types/config.ts
485
- var DEFAULT_DOCS_CONFIG = {
486
- enabled: true,
487
- path: "/docs",
488
- ui: "scalar",
489
- openApi: {
490
- info: {
491
- title: "Nural API",
492
- version: "1.0.0",
493
- description: "Powered by Nural Framework"
494
- },
495
- servers: [{ url: "/" }]
496
- },
497
- scalar: {},
498
- swagger: {}
499
- };
500
- function resolveDocsConfig(docs) {
501
- if (docs === false) {
502
- return { ...DEFAULT_DOCS_CONFIG, enabled: false };
503
- }
504
- if (docs === true || docs === void 0) {
505
- return DEFAULT_DOCS_CONFIG;
506
- }
507
- return {
508
- enabled: docs.enabled ?? true,
509
- path: docs.path ?? DEFAULT_DOCS_CONFIG.path,
510
- ui: docs.ui ?? DEFAULT_DOCS_CONFIG.ui,
511
- openApi: {
512
- ...DEFAULT_DOCS_CONFIG.openApi,
513
- ...docs.openApi,
514
- info: {
515
- ...DEFAULT_DOCS_CONFIG.openApi.info,
516
- ...docs.openApi?.info,
517
- // Backward compatibility: use top-level fields if provided
518
- title: docs.title ?? docs.openApi?.info?.title ?? DEFAULT_DOCS_CONFIG.openApi.info?.title,
519
- version: docs.version ?? docs.openApi?.info?.version ?? DEFAULT_DOCS_CONFIG.openApi.info?.version,
520
- description: docs.description ?? docs.openApi?.info?.description ?? DEFAULT_DOCS_CONFIG.openApi.info?.description
521
- }
522
- },
523
- scalar: docs.scalar ?? {},
524
- swagger: docs.swagger ?? {}
525
- };
526
- }
527
-
528
- // src/types/middleware.ts
529
- var DEFAULT_CORS_CONFIG = {
530
- origin: "*",
531
- methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
532
- allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
533
- exposedHeaders: [],
534
- credentials: false,
535
- maxAge: 86400,
536
- // 24 hours
537
- preflightContinue: false,
538
- optionsSuccessStatus: 204
539
- };
540
- var DEFAULT_HELMET_CONFIG = {
541
- contentSecurityPolicy: false,
542
- // Disabled by default (can break apps)
543
- crossOriginEmbedderPolicy: false,
544
- crossOriginOpenerPolicy: { policy: "same-origin" },
545
- crossOriginResourcePolicy: { policy: "same-origin" },
546
- dnsPrefetchControl: { allow: false },
547
- frameguard: { action: "sameorigin" },
548
- hsts: { maxAge: 15552e3, includeSubDomains: true, preload: false },
549
- // 180 days
550
- noSniff: true,
551
- permittedCrossDomainPolicies: { policy: "none" },
552
- referrerPolicy: { policy: "no-referrer" },
553
- xssFilter: false
554
- // Deprecated, browsers ignore it
555
- };
556
- function resolveCorsConfig(cors) {
557
- if (cors === false || cors === void 0) {
558
- return null;
559
- }
560
- if (cors === true) {
561
- return DEFAULT_CORS_CONFIG;
562
- }
563
- return {
564
- origin: cors.origin ?? DEFAULT_CORS_CONFIG.origin,
565
- methods: cors.methods ?? DEFAULT_CORS_CONFIG.methods,
566
- allowedHeaders: cors.allowedHeaders ?? DEFAULT_CORS_CONFIG.allowedHeaders,
567
- exposedHeaders: cors.exposedHeaders ?? DEFAULT_CORS_CONFIG.exposedHeaders,
568
- credentials: cors.credentials ?? DEFAULT_CORS_CONFIG.credentials,
569
- maxAge: cors.maxAge ?? DEFAULT_CORS_CONFIG.maxAge,
570
- preflightContinue: cors.preflightContinue ?? DEFAULT_CORS_CONFIG.preflightContinue,
571
- optionsSuccessStatus: cors.optionsSuccessStatus ?? DEFAULT_CORS_CONFIG.optionsSuccessStatus
572
- };
573
- }
574
- function resolveHelmetConfig(helmet) {
575
- if (helmet === false || helmet === void 0) {
576
- return null;
577
- }
578
- if (helmet === true) {
579
- return DEFAULT_HELMET_CONFIG;
580
- }
581
- return {
582
- contentSecurityPolicy: typeof helmet.contentSecurityPolicy === "object" ? { directives: helmet.contentSecurityPolicy.directives ?? {} } : helmet.contentSecurityPolicy ?? DEFAULT_HELMET_CONFIG.contentSecurityPolicy,
583
- crossOriginEmbedderPolicy: helmet.crossOriginEmbedderPolicy ?? DEFAULT_HELMET_CONFIG.crossOriginEmbedderPolicy,
584
- crossOriginOpenerPolicy: typeof helmet.crossOriginOpenerPolicy === "object" ? helmet.crossOriginOpenerPolicy : DEFAULT_HELMET_CONFIG.crossOriginOpenerPolicy,
585
- crossOriginResourcePolicy: typeof helmet.crossOriginResourcePolicy === "object" ? helmet.crossOriginResourcePolicy : DEFAULT_HELMET_CONFIG.crossOriginResourcePolicy,
586
- dnsPrefetchControl: typeof helmet.dnsPrefetchControl === "object" ? helmet.dnsPrefetchControl : DEFAULT_HELMET_CONFIG.dnsPrefetchControl,
587
- frameguard: typeof helmet.frameguard === "object" ? helmet.frameguard : DEFAULT_HELMET_CONFIG.frameguard,
588
- hsts: typeof helmet.hsts === "object" ? { ...DEFAULT_HELMET_CONFIG.hsts, ...helmet.hsts } : DEFAULT_HELMET_CONFIG.hsts,
589
- noSniff: helmet.noSniff ?? DEFAULT_HELMET_CONFIG.noSniff,
590
- permittedCrossDomainPolicies: typeof helmet.permittedCrossDomainPolicies === "object" ? helmet.permittedCrossDomainPolicies : DEFAULT_HELMET_CONFIG.permittedCrossDomainPolicies,
591
- referrerPolicy: typeof helmet.referrerPolicy === "object" ? helmet.referrerPolicy : DEFAULT_HELMET_CONFIG.referrerPolicy,
592
- xssFilter: helmet.xssFilter ?? DEFAULT_HELMET_CONFIG.xssFilter
593
- };
594
- }
595
489
  var DocumentationGenerator = class {
596
490
  constructor(config) {
597
491
  this.registry = new OpenAPIRegistry();
@@ -982,6 +876,118 @@ var httpLogger = (options = {}) => {
982
876
  };
983
877
  };
984
878
 
879
+ // src/types/config.ts
880
+ var DEFAULT_DOCS_CONFIG = {
881
+ enabled: true,
882
+ path: "/docs",
883
+ ui: "scalar",
884
+ openApi: {
885
+ info: {
886
+ title: "Nural API",
887
+ version: "1.0.0",
888
+ description: "Powered by Nural Framework"
889
+ },
890
+ servers: [{ url: "/" }]
891
+ },
892
+ scalar: {},
893
+ swagger: {}
894
+ };
895
+ function resolveDocsConfig(docs) {
896
+ if (docs === false) {
897
+ return { ...DEFAULT_DOCS_CONFIG, enabled: false };
898
+ }
899
+ if (docs === true || docs === void 0) {
900
+ return DEFAULT_DOCS_CONFIG;
901
+ }
902
+ return {
903
+ enabled: docs.enabled ?? true,
904
+ path: docs.path ?? DEFAULT_DOCS_CONFIG.path,
905
+ ui: docs.ui ?? DEFAULT_DOCS_CONFIG.ui,
906
+ openApi: {
907
+ ...DEFAULT_DOCS_CONFIG.openApi,
908
+ ...docs.openApi,
909
+ info: {
910
+ ...DEFAULT_DOCS_CONFIG.openApi.info,
911
+ ...docs.openApi?.info,
912
+ // Backward compatibility: use top-level fields if provided
913
+ title: docs.title ?? docs.openApi?.info?.title ?? DEFAULT_DOCS_CONFIG.openApi.info?.title,
914
+ version: docs.version ?? docs.openApi?.info?.version ?? DEFAULT_DOCS_CONFIG.openApi.info?.version,
915
+ description: docs.description ?? docs.openApi?.info?.description ?? DEFAULT_DOCS_CONFIG.openApi.info?.description
916
+ }
917
+ },
918
+ scalar: docs.scalar ?? {},
919
+ swagger: docs.swagger ?? {}
920
+ };
921
+ }
922
+
923
+ // src/types/middleware.ts
924
+ var DEFAULT_CORS_CONFIG = {
925
+ origin: "*",
926
+ methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
927
+ allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
928
+ exposedHeaders: [],
929
+ credentials: false,
930
+ maxAge: 86400,
931
+ // 24 hours
932
+ preflightContinue: false,
933
+ optionsSuccessStatus: 204
934
+ };
935
+ var DEFAULT_HELMET_CONFIG = {
936
+ contentSecurityPolicy: false,
937
+ // Disabled by default (can break apps)
938
+ crossOriginEmbedderPolicy: false,
939
+ crossOriginOpenerPolicy: { policy: "same-origin" },
940
+ crossOriginResourcePolicy: { policy: "same-origin" },
941
+ dnsPrefetchControl: { allow: false },
942
+ frameguard: { action: "sameorigin" },
943
+ hsts: { maxAge: 15552e3, includeSubDomains: true, preload: false },
944
+ // 180 days
945
+ noSniff: true,
946
+ permittedCrossDomainPolicies: { policy: "none" },
947
+ referrerPolicy: { policy: "no-referrer" },
948
+ xssFilter: false
949
+ // Deprecated, browsers ignore it
950
+ };
951
+ function resolveCorsConfig(cors) {
952
+ if (cors === false || cors === void 0) {
953
+ return null;
954
+ }
955
+ if (cors === true) {
956
+ return DEFAULT_CORS_CONFIG;
957
+ }
958
+ return {
959
+ origin: cors.origin ?? DEFAULT_CORS_CONFIG.origin,
960
+ methods: cors.methods ?? DEFAULT_CORS_CONFIG.methods,
961
+ allowedHeaders: cors.allowedHeaders ?? DEFAULT_CORS_CONFIG.allowedHeaders,
962
+ exposedHeaders: cors.exposedHeaders ?? DEFAULT_CORS_CONFIG.exposedHeaders,
963
+ credentials: cors.credentials ?? DEFAULT_CORS_CONFIG.credentials,
964
+ maxAge: cors.maxAge ?? DEFAULT_CORS_CONFIG.maxAge,
965
+ preflightContinue: cors.preflightContinue ?? DEFAULT_CORS_CONFIG.preflightContinue,
966
+ optionsSuccessStatus: cors.optionsSuccessStatus ?? DEFAULT_CORS_CONFIG.optionsSuccessStatus
967
+ };
968
+ }
969
+ function resolveHelmetConfig(helmet) {
970
+ if (helmet === false || helmet === void 0) {
971
+ return null;
972
+ }
973
+ if (helmet === true) {
974
+ return DEFAULT_HELMET_CONFIG;
975
+ }
976
+ return {
977
+ contentSecurityPolicy: typeof helmet.contentSecurityPolicy === "object" ? { directives: helmet.contentSecurityPolicy.directives ?? {} } : helmet.contentSecurityPolicy ?? DEFAULT_HELMET_CONFIG.contentSecurityPolicy,
978
+ crossOriginEmbedderPolicy: helmet.crossOriginEmbedderPolicy ?? DEFAULT_HELMET_CONFIG.crossOriginEmbedderPolicy,
979
+ crossOriginOpenerPolicy: typeof helmet.crossOriginOpenerPolicy === "object" ? helmet.crossOriginOpenerPolicy : DEFAULT_HELMET_CONFIG.crossOriginOpenerPolicy,
980
+ crossOriginResourcePolicy: typeof helmet.crossOriginResourcePolicy === "object" ? helmet.crossOriginResourcePolicy : DEFAULT_HELMET_CONFIG.crossOriginResourcePolicy,
981
+ dnsPrefetchControl: typeof helmet.dnsPrefetchControl === "object" ? helmet.dnsPrefetchControl : DEFAULT_HELMET_CONFIG.dnsPrefetchControl,
982
+ frameguard: typeof helmet.frameguard === "object" ? helmet.frameguard : DEFAULT_HELMET_CONFIG.frameguard,
983
+ hsts: typeof helmet.hsts === "object" ? { ...DEFAULT_HELMET_CONFIG.hsts, ...helmet.hsts } : DEFAULT_HELMET_CONFIG.hsts,
984
+ noSniff: helmet.noSniff ?? DEFAULT_HELMET_CONFIG.noSniff,
985
+ permittedCrossDomainPolicies: typeof helmet.permittedCrossDomainPolicies === "object" ? helmet.permittedCrossDomainPolicies : DEFAULT_HELMET_CONFIG.permittedCrossDomainPolicies,
986
+ referrerPolicy: typeof helmet.referrerPolicy === "object" ? helmet.referrerPolicy : DEFAULT_HELMET_CONFIG.referrerPolicy,
987
+ xssFilter: helmet.xssFilter ?? DEFAULT_HELMET_CONFIG.xssFilter
988
+ };
989
+ }
990
+
985
991
  // src/core/nural.ts
986
992
  var Nural = class {
987
993
  constructor(config = {}) {
@@ -1007,6 +1013,9 @@ var Nural = class {
1007
1013
  }
1008
1014
  this.applyBuiltInMiddleware();
1009
1015
  }
1016
+ get server() {
1017
+ return this.adapter.server;
1018
+ }
1010
1019
  /**
1011
1020
  * Apply CORS and Helmet middleware based on config
1012
1021
  */
@@ -1046,7 +1055,7 @@ var Nural = class {
1046
1055
  if (this.docsConfig.enabled) {
1047
1056
  this.setupDocs();
1048
1057
  }
1049
- this.adapter.listen(port, () => {
1058
+ return this.adapter.listen(port, () => {
1050
1059
  console.log(`\u{1F680} Nural Server running on port ${port}`);
1051
1060
  if (this.docsConfig.enabled) {
1052
1061
  console.log(