adorn-api 1.0.14 → 1.0.16

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/express.js CHANGED
@@ -932,35 +932,122 @@ async function createExpressRouter(options) {
932
932
 
933
933
  // src/adapter/express/swagger.ts
934
934
  import { Router as Router2 } from "express";
935
- import { readFileSync } from "fs";
936
- import { resolve, isAbsolute } from "path";
935
+ import { readFileSync, existsSync } from "fs";
936
+ import { resolve, isAbsolute, join as join2 } from "path";
937
937
  import swaggerUi from "swagger-ui-express";
938
+ var DEFAULT_SWAGGER_UI_OPTIONS = {
939
+ docExpansion: "none",
940
+ // Collapse all by default for better performance
941
+ filter: true,
942
+ // Show filter input
943
+ showRequestDuration: true,
944
+ // Show request duration
945
+ displayRequestDuration: true,
946
+ operationsSorter: "alpha",
947
+ // Sort operations alphabetically
948
+ tagsSorter: "alpha",
949
+ // Sort tags alphabetically
950
+ persistAuthorization: true
951
+ // Persist authorization across reloads
952
+ };
953
+ function isSplitMode(openapiPath) {
954
+ const schemasDir = join2(openapiPath, "..", "schemas");
955
+ return existsSync(schemasDir);
956
+ }
957
+ function createSchemaRouter(artifactsDir) {
958
+ const router = Router2();
959
+ const schemasDir = isAbsolute(artifactsDir) ? resolve(artifactsDir, "schemas") : resolve(process.cwd(), artifactsDir, "schemas");
960
+ router.get("/schemas/:filename", (req, res, next) => {
961
+ const { filename } = req.params;
962
+ const filePath = resolve(schemasDir, filename);
963
+ if (!existsSync(filePath)) {
964
+ return res.status(404).json({ error: "Schema file not found" });
965
+ }
966
+ try {
967
+ const content = readFileSync(filePath, "utf-8");
968
+ res.setHeader("Content-Type", "application/json");
969
+ res.send(content);
970
+ } catch (error) {
971
+ next(error);
972
+ }
973
+ });
974
+ return router;
975
+ }
938
976
  function setupSwagger(options = {}) {
939
977
  const {
940
978
  artifactsDir = ".adorn",
941
979
  jsonPath = "/docs/openapi.json",
942
980
  uiPath = "/docs",
943
- swaggerOptions = {}
981
+ swaggerOptions = {},
982
+ swaggerUiOptions = {}
944
983
  } = options;
945
984
  const router = Router2();
985
+ const openApiPath = isAbsolute(artifactsDir) ? resolve(artifactsDir, "openapi.json") : resolve(process.cwd(), artifactsDir, "openapi.json");
986
+ const splitMode = isSplitMode(openApiPath);
946
987
  router.get(jsonPath, (req, res) => {
947
- const openApiPath = isAbsolute(artifactsDir) ? resolve(artifactsDir, "openapi.json") : resolve(process.cwd(), artifactsDir, "openapi.json");
988
+ if (!existsSync(openApiPath)) {
989
+ return res.status(404).json({ error: "OpenAPI spec not found" });
990
+ }
948
991
  const content = readFileSync(openApiPath, "utf-8");
949
992
  res.setHeader("Content-Type", "application/json");
950
993
  res.send(content);
951
994
  });
995
+ if (splitMode) {
996
+ router.use("/schemas", createSchemaRouter(artifactsDir));
997
+ }
998
+ const mergedSwaggerOptions = {
999
+ ...DEFAULT_SWAGGER_UI_OPTIONS,
1000
+ ...swaggerOptions
1001
+ };
952
1002
  router.use(uiPath, swaggerUi.serve, swaggerUi.setup(null, {
953
1003
  swaggerOptions: {
954
1004
  url: jsonPath,
955
- ...swaggerOptions
956
- }
1005
+ ...mergedSwaggerOptions,
1006
+ // Add support for external $ref references in split mode
1007
+ supportedSubmitMethods: ["get", "put", "post", "delete", "options", "head", "patch"]
1008
+ },
1009
+ ...swaggerUiOptions
957
1010
  }));
958
1011
  return router;
959
1012
  }
960
1013
 
961
1014
  // src/adapter/express/bootstrap.ts
962
1015
  import express from "express";
1016
+ import cors from "cors";
963
1017
  import path2 from "path";
1018
+ var DEFAULT_CORS_CONFIG = {
1019
+ origin: (origin, callback) => {
1020
+ const allowedOrigins = process.env.CORS_ALLOWED_ORIGINS ? process.env.CORS_ALLOWED_ORIGINS.split(",") : ["http://localhost:*", "http://127.0.0.1:*"];
1021
+ if (!origin) {
1022
+ return callback(null, true);
1023
+ }
1024
+ const isAllowed = allowedOrigins.some((allowed) => {
1025
+ if (allowed === "*") return true;
1026
+ if (allowed.includes("*")) {
1027
+ const regex = new RegExp(allowed.replace("*", ".*"));
1028
+ return regex.test(origin);
1029
+ }
1030
+ return origin === allowed;
1031
+ });
1032
+ callback(null, isAllowed);
1033
+ },
1034
+ methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
1035
+ allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
1036
+ credentials: false,
1037
+ optionsSuccessStatus: 204,
1038
+ maxAge: 86400
1039
+ };
1040
+ function applyCors(app, config) {
1041
+ if (typeof config === "function") {
1042
+ config(app);
1043
+ return;
1044
+ }
1045
+ if (config === true) {
1046
+ app.use(cors(DEFAULT_CORS_CONFIG));
1047
+ return;
1048
+ }
1049
+ app.use(cors(config));
1050
+ }
964
1051
  function bootstrap(options) {
965
1052
  return new Promise((resolve2, reject) => {
966
1053
  const {
@@ -973,7 +1060,8 @@ function bootstrap(options) {
973
1060
  swaggerJsonPath = "/docs/openapi.json",
974
1061
  middleware,
975
1062
  auth,
976
- coerce
1063
+ coerce,
1064
+ cors: cors2
977
1065
  } = options;
978
1066
  if (controllers.length === 0) {
979
1067
  reject(new Error("At least one controller must be provided to bootstrap()."));
@@ -989,6 +1077,9 @@ function bootstrap(options) {
989
1077
  const absoluteArtifactsDir = path2.isAbsolute(userArtifactsDir) ? userArtifactsDir : path2.resolve(process.cwd(), userArtifactsDir);
990
1078
  const app = express();
991
1079
  app.use(express.json());
1080
+ if (cors2 !== void 0 && cors2 !== false) {
1081
+ applyCors(app, cors2);
1082
+ }
992
1083
  createExpressRouter({
993
1084
  controllers,
994
1085
  artifactsDir: absoluteArtifactsDir,
@@ -1006,8 +1097,10 @@ function bootstrap(options) {
1006
1097
  jsonPath: swaggerJsonPath,
1007
1098
  uiPath: swaggerPath,
1008
1099
  swaggerOptions: {
1009
- servers: [{ url: serverUrl }]
1010
- }
1100
+ servers: [{ url: serverUrl }],
1101
+ ...options.swaggerOptions
1102
+ },
1103
+ swaggerUiOptions: options.swaggerUiOptions
1011
1104
  })
1012
1105
  );
1013
1106
  }