@terreno/api 0.7.0 → 0.7.2

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.
Files changed (40) hide show
  1. package/dist/__tests__/versionCheck.test.d.ts +1 -0
  2. package/dist/__tests__/versionCheck.test.js +263 -0
  3. package/dist/expressServer.js +2 -2
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.js +2 -0
  6. package/dist/models/versionConfig.d.ts +17 -0
  7. package/dist/models/versionConfig.js +66 -0
  8. package/dist/terrenoApp.js +2 -2
  9. package/dist/vendor/wesleytodd-openapi/index.d.ts +27 -0
  10. package/dist/vendor/wesleytodd-openapi/index.js +176 -0
  11. package/dist/vendor/wesleytodd-openapi/lib/convert-yaml.d.ts +2 -0
  12. package/dist/vendor/wesleytodd-openapi/lib/convert-yaml.js +13 -0
  13. package/dist/vendor/wesleytodd-openapi/lib/generate-doc.d.ts +2 -0
  14. package/dist/vendor/wesleytodd-openapi/lib/generate-doc.js +148 -0
  15. package/dist/vendor/wesleytodd-openapi/lib/layer-schema.d.ts +2 -0
  16. package/dist/vendor/wesleytodd-openapi/lib/layer-schema.js +12 -0
  17. package/dist/vendor/wesleytodd-openapi/lib/minimum-doc.d.ts +6 -0
  18. package/dist/vendor/wesleytodd-openapi/lib/minimum-doc.js +11 -0
  19. package/dist/vendor/wesleytodd-openapi/lib/ui.d.ts +1 -0
  20. package/dist/vendor/wesleytodd-openapi/lib/ui.js +37 -0
  21. package/dist/vendor/wesleytodd-openapi/lib/validate.d.ts +2 -0
  22. package/dist/vendor/wesleytodd-openapi/lib/validate.js +168 -0
  23. package/dist/versionCheckPlugin.d.ts +15 -0
  24. package/dist/versionCheckPlugin.js +106 -0
  25. package/package.json +9 -2
  26. package/src/__tests__/versionCheck.test.ts +132 -0
  27. package/src/expressServer.ts +1 -2
  28. package/src/index.ts +2 -0
  29. package/src/models/versionConfig.ts +92 -0
  30. package/src/terrenoApp.ts +1 -2
  31. package/src/vendor/wesleytodd-openapi/LICENSE +15 -0
  32. package/src/vendor/wesleytodd-openapi/index.js +189 -0
  33. package/src/vendor/wesleytodd-openapi/lib/convert-yaml.js +13 -0
  34. package/src/vendor/wesleytodd-openapi/lib/generate-doc.js +153 -0
  35. package/src/vendor/wesleytodd-openapi/lib/layer-schema.js +13 -0
  36. package/src/vendor/wesleytodd-openapi/lib/minimum-doc.js +12 -0
  37. package/src/vendor/wesleytodd-openapi/lib/ui.js +71 -0
  38. package/src/vendor/wesleytodd-openapi/lib/validate.js +152 -0
  39. package/src/versionCheckPlugin.ts +81 -0
  40. package/tsconfig.json +1 -1
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ var bun_test_1 = require("bun:test");
43
+ var supertest_1 = __importDefault(require("supertest"));
44
+ var versionConfig_1 = require("../models/versionConfig");
45
+ var terrenoApp_1 = require("../terrenoApp");
46
+ var tests_1 = require("../tests");
47
+ var versionCheckPlugin_1 = require("../versionCheckPlugin");
48
+ (0, bun_test_1.describe)("VersionCheckPlugin", function () {
49
+ var app;
50
+ (0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
51
+ var expressApp;
52
+ return __generator(this, function (_a) {
53
+ switch (_a.label) {
54
+ case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
55
+ case 1:
56
+ _a.sent();
57
+ return [4 /*yield*/, versionConfig_1.VersionConfig.deleteMany({})];
58
+ case 2:
59
+ _a.sent();
60
+ expressApp = new terrenoApp_1.TerrenoApp({
61
+ skipListen: true,
62
+ userModel: tests_1.UserModel,
63
+ })
64
+ .register(new versionCheckPlugin_1.VersionCheckPlugin())
65
+ .build();
66
+ app = (0, supertest_1.default)(expressApp);
67
+ return [2 /*return*/];
68
+ }
69
+ });
70
+ }); });
71
+ (0, bun_test_1.afterEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
72
+ return __generator(this, function (_a) {
73
+ switch (_a.label) {
74
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.deleteMany({})];
75
+ case 1:
76
+ _a.sent();
77
+ return [2 /*return*/];
78
+ }
79
+ });
80
+ }); });
81
+ (0, bun_test_1.it)("returns ok when no VersionConfig exists", function () { return __awaiter(void 0, void 0, void 0, function () {
82
+ var res;
83
+ return __generator(this, function (_a) {
84
+ switch (_a.label) {
85
+ case 0: return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 100 })];
86
+ case 1:
87
+ res = _a.sent();
88
+ (0, bun_test_1.expect)(res.status).toBe(200);
89
+ (0, bun_test_1.expect)(res.body).toEqual({ status: "ok" });
90
+ return [2 /*return*/];
91
+ }
92
+ });
93
+ }); });
94
+ (0, bun_test_1.it)("returns ok when version param is missing", function () { return __awaiter(void 0, void 0, void 0, function () {
95
+ var res;
96
+ return __generator(this, function (_a) {
97
+ switch (_a.label) {
98
+ case 0: return [4 /*yield*/, app.get("/version-check")];
99
+ case 1:
100
+ res = _a.sent();
101
+ (0, bun_test_1.expect)(res.status).toBe(200);
102
+ (0, bun_test_1.expect)(res.body).toEqual({ status: "ok" });
103
+ return [2 /*return*/];
104
+ }
105
+ });
106
+ }); });
107
+ (0, bun_test_1.it)("returns ok when version param is invalid", function () { return __awaiter(void 0, void 0, void 0, function () {
108
+ var res;
109
+ return __generator(this, function (_a) {
110
+ switch (_a.label) {
111
+ case 0: return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: "invalid" })];
112
+ case 1:
113
+ res = _a.sent();
114
+ (0, bun_test_1.expect)(res.status).toBe(200);
115
+ (0, bun_test_1.expect)(res.body).toEqual({ status: "ok" });
116
+ return [2 /*return*/];
117
+ }
118
+ });
119
+ }); });
120
+ (0, bun_test_1.it)("returns ok when client version >= warning and required (web)", function () { return __awaiter(void 0, void 0, void 0, function () {
121
+ var res;
122
+ return __generator(this, function (_a) {
123
+ switch (_a.label) {
124
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
125
+ webRequiredVersion: 50,
126
+ webWarningVersion: 100,
127
+ })];
128
+ case 1:
129
+ _a.sent();
130
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 150 })];
131
+ case 2:
132
+ res = _a.sent();
133
+ (0, bun_test_1.expect)(res.status).toBe(200);
134
+ (0, bun_test_1.expect)(res.body).toEqual({ status: "ok" });
135
+ return [2 /*return*/];
136
+ }
137
+ });
138
+ }); });
139
+ (0, bun_test_1.it)("returns warning when client version < warning (web)", function () { return __awaiter(void 0, void 0, void 0, function () {
140
+ var res;
141
+ return __generator(this, function (_a) {
142
+ switch (_a.label) {
143
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
144
+ warningMessage: "Please update!",
145
+ webRequiredVersion: 50,
146
+ webWarningVersion: 100,
147
+ })];
148
+ case 1:
149
+ _a.sent();
150
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 80 })];
151
+ case 2:
152
+ res = _a.sent();
153
+ (0, bun_test_1.expect)(res.status).toBe(200);
154
+ (0, bun_test_1.expect)(res.body.status).toBe("warning");
155
+ (0, bun_test_1.expect)(res.body.message).toBe("Please update!");
156
+ return [2 /*return*/];
157
+ }
158
+ });
159
+ }); });
160
+ (0, bun_test_1.it)("returns required when client version < required (web)", function () { return __awaiter(void 0, void 0, void 0, function () {
161
+ var res;
162
+ return __generator(this, function (_a) {
163
+ switch (_a.label) {
164
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
165
+ requiredMessage: "Update required",
166
+ updateUrl: "https://example.com/update",
167
+ webRequiredVersion: 100,
168
+ webWarningVersion: 150,
169
+ })];
170
+ case 1:
171
+ _a.sent();
172
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 50 })];
173
+ case 2:
174
+ res = _a.sent();
175
+ (0, bun_test_1.expect)(res.status).toBe(200);
176
+ (0, bun_test_1.expect)(res.body.status).toBe("required");
177
+ (0, bun_test_1.expect)(res.body.message).toBe("Update required");
178
+ (0, bun_test_1.expect)(res.body.updateUrl).toBe("https://example.com/update");
179
+ return [2 /*return*/];
180
+ }
181
+ });
182
+ }); });
183
+ (0, bun_test_1.it)("uses mobile thresholds when platform is mobile", function () { return __awaiter(void 0, void 0, void 0, function () {
184
+ var webRes, mobileRes;
185
+ return __generator(this, function (_a) {
186
+ switch (_a.label) {
187
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
188
+ mobileRequiredVersion: 200,
189
+ mobileWarningVersion: 250,
190
+ webRequiredVersion: 50,
191
+ webWarningVersion: 80,
192
+ })];
193
+ case 1:
194
+ _a.sent();
195
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 100 })];
196
+ case 2:
197
+ webRes = _a.sent();
198
+ (0, bun_test_1.expect)(webRes.body.status).toBe("ok");
199
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "mobile", version: 100 })];
200
+ case 3:
201
+ mobileRes = _a.sent();
202
+ (0, bun_test_1.expect)(mobileRes.body.status).toBe("required");
203
+ return [2 /*return*/];
204
+ }
205
+ });
206
+ }); });
207
+ (0, bun_test_1.it)("defaults to web when platform is invalid", function () { return __awaiter(void 0, void 0, void 0, function () {
208
+ var res;
209
+ return __generator(this, function (_a) {
210
+ switch (_a.label) {
211
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
212
+ webRequiredVersion: 100,
213
+ webWarningVersion: 150,
214
+ })];
215
+ case 1:
216
+ _a.sent();
217
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "invalid", version: 50 })];
218
+ case 2:
219
+ res = _a.sent();
220
+ (0, bun_test_1.expect)(res.body.status).toBe("required");
221
+ return [2 /*return*/];
222
+ }
223
+ });
224
+ }); });
225
+ (0, bun_test_1.it)("version equal to threshold returns ok (not warning)", function () { return __awaiter(void 0, void 0, void 0, function () {
226
+ var res;
227
+ return __generator(this, function (_a) {
228
+ switch (_a.label) {
229
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
230
+ webRequiredVersion: 50,
231
+ webWarningVersion: 100,
232
+ })];
233
+ case 1:
234
+ _a.sent();
235
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 100 })];
236
+ case 2:
237
+ res = _a.sent();
238
+ (0, bun_test_1.expect)(res.status).toBe(200);
239
+ (0, bun_test_1.expect)(res.body).toEqual({ status: "ok" });
240
+ return [2 /*return*/];
241
+ }
242
+ });
243
+ }); });
244
+ (0, bun_test_1.it)("version equal to required returns warning not required", function () { return __awaiter(void 0, void 0, void 0, function () {
245
+ var res;
246
+ return __generator(this, function (_a) {
247
+ switch (_a.label) {
248
+ case 0: return [4 /*yield*/, versionConfig_1.VersionConfig.create({
249
+ webRequiredVersion: 100,
250
+ webWarningVersion: 150,
251
+ })];
252
+ case 1:
253
+ _a.sent();
254
+ return [4 /*yield*/, app.get("/version-check").query({ platform: "web", version: 100 })];
255
+ case 2:
256
+ res = _a.sent();
257
+ (0, bun_test_1.expect)(res.status).toBe(200);
258
+ (0, bun_test_1.expect)(res.body.status).toBe("warning");
259
+ return [2 /*return*/];
260
+ }
261
+ });
262
+ }); });
263
+ });
@@ -105,7 +105,6 @@ exports.setupServer = setupServer;
105
105
  exports.cronjob = cronjob;
106
106
  exports.wrapScript = wrapScript;
107
107
  var Sentry = __importStar(require("@sentry/bun"));
108
- var openapi_1 = __importDefault(require("@wesleytodd/openapi"));
109
108
  var cors_1 = __importDefault(require("cors"));
110
109
  var cron_1 = __importDefault(require("cron"));
111
110
  var express_1 = __importDefault(require("express"));
@@ -120,6 +119,7 @@ var logger_1 = require("./logger");
120
119
  var notifiers_1 = require("./notifiers");
121
120
  var openApiCompat_1 = require("./openApiCompat");
122
121
  var openApiEtag_1 = require("./openApiEtag");
122
+ var index_1 = __importDefault(require("./vendor/wesleytodd-openapi/index"));
123
123
  var SLOW_READ_MAX = 200;
124
124
  var SLOW_WRITE_MAX = 500;
125
125
  var IS_JEST = process.env.JEST_WORKER_ID !== undefined;
@@ -276,7 +276,7 @@ function initializeRoutes(UserModel, addRoutes, options) {
276
276
  // Add ETag middleware for OpenAPI JSON endpoint before the openapi middleware
277
277
  app.use(openApiCompat_1.openApiCompatMiddleware);
278
278
  app.use(openApiEtag_1.openApiEtagMiddleware);
279
- var oapi = (0, openapi_1.default)({
279
+ var oapi = (0, index_1.default)({
280
280
  info: {
281
281
  description: "Generated docs from an Express api",
282
282
  title: "Express Application",
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * from "./expressServer";
10
10
  export * from "./githubAuth";
11
11
  export * from "./logger";
12
12
  export * from "./middleware";
13
+ export * from "./models/versionConfig";
13
14
  export * from "./notifiers";
14
15
  export * from "./openApiBuilder";
15
16
  export * from "./openApiCompat";
@@ -24,3 +25,4 @@ export * from "./terrenoApp";
24
25
  export * from "./terrenoPlugin";
25
26
  export * from "./transformers";
26
27
  export * from "./utils";
28
+ export * from "./versionCheckPlugin";
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ __exportStar(require("./expressServer"), exports);
26
26
  __exportStar(require("./githubAuth"), exports);
27
27
  __exportStar(require("./logger"), exports);
28
28
  __exportStar(require("./middleware"), exports);
29
+ __exportStar(require("./models/versionConfig"), exports);
29
30
  __exportStar(require("./notifiers"), exports);
30
31
  __exportStar(require("./openApiBuilder"), exports);
31
32
  __exportStar(require("./openApiCompat"), exports);
@@ -40,3 +41,4 @@ __exportStar(require("./terrenoApp"), exports);
40
41
  __exportStar(require("./terrenoPlugin"), exports);
41
42
  __exportStar(require("./transformers"), exports);
42
43
  __exportStar(require("./utils"), exports);
44
+ __exportStar(require("./versionCheckPlugin"), exports);
@@ -0,0 +1,17 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ import { type APIErrorConstructor } from "../errors";
3
+ export interface VersionConfigDocument extends mongoose.Document {
4
+ webWarningVersion: number;
5
+ webRequiredVersion: number;
6
+ mobileWarningVersion: number;
7
+ mobileRequiredVersion: number;
8
+ warningMessage: string;
9
+ requiredMessage: string;
10
+ updateUrl?: string;
11
+ created?: Date;
12
+ updated?: Date;
13
+ }
14
+ export interface VersionConfigModel extends mongoose.Model<VersionConfigDocument> {
15
+ findOneOrNone(query: Record<string, any>, errorArgs?: Partial<APIErrorConstructor>): Promise<(Document & VersionConfigDocument) | null>;
16
+ }
17
+ export declare const VersionConfig: VersionConfigModel;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VersionConfig = void 0;
7
+ var mongoose_1 = __importDefault(require("mongoose"));
8
+ var plugins_1 = require("../plugins");
9
+ var versionConfigSchema = new mongoose_1.default.Schema({
10
+ mobileRequiredVersion: {
11
+ default: 0,
12
+ description: "Build number at which mobile users are blocked from using the app",
13
+ min: 0,
14
+ type: Number,
15
+ },
16
+ mobileWarningVersion: {
17
+ default: 0,
18
+ description: "Build number at which mobile users see a warning toast",
19
+ min: 0,
20
+ type: Number,
21
+ },
22
+ requiredMessage: {
23
+ default: "This version is no longer supported. Please update to continue.",
24
+ description: "Message shown on the blocking screen",
25
+ type: String,
26
+ },
27
+ updateUrl: {
28
+ description: "App store or download URL for mobile updates (optional, falls back to expo-updates)",
29
+ type: String,
30
+ },
31
+ warningMessage: {
32
+ default: "A new version is available. Please update for the best experience.",
33
+ description: "Message shown in the warning toast",
34
+ type: String,
35
+ },
36
+ webRequiredVersion: {
37
+ default: 0,
38
+ description: "Build number at which web users are blocked from using the app",
39
+ min: 0,
40
+ type: Number,
41
+ },
42
+ webWarningVersion: {
43
+ default: 0,
44
+ description: "Build number at which web users see a warning toast",
45
+ min: 0,
46
+ type: Number,
47
+ },
48
+ }, { strict: "throw", toJSON: { virtuals: true }, toObject: { virtuals: true } });
49
+ // Enforce singleton: only one VersionConfig document can exist.
50
+ // The _singleton field is always "config" (required, immutable, enum-constrained)
51
+ // and a unique index guarantees at most one document.
52
+ versionConfigSchema.add({
53
+ _singleton: {
54
+ default: "config",
55
+ description: "Sentinel field to enforce singleton via unique index",
56
+ enum: ["config"],
57
+ immutable: true,
58
+ required: true,
59
+ select: false,
60
+ type: String,
61
+ },
62
+ });
63
+ versionConfigSchema.index({ _singleton: 1 }, { unique: true });
64
+ versionConfigSchema.plugin(plugins_1.createdUpdatedPlugin);
65
+ versionConfigSchema.plugin(plugins_1.findOneOrNone);
66
+ exports.VersionConfig = mongoose_1.default.model("VersionConfig", versionConfigSchema);
@@ -60,7 +60,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
60
60
  Object.defineProperty(exports, "__esModule", { value: true });
61
61
  exports.TerrenoApp = void 0;
62
62
  var Sentry = __importStar(require("@sentry/bun"));
63
- var openapi_1 = __importDefault(require("@wesleytodd/openapi"));
64
63
  var cors_1 = __importDefault(require("cors"));
65
64
  var express_1 = __importDefault(require("express"));
66
65
  var qs_1 = __importDefault(require("qs"));
@@ -72,6 +71,7 @@ var githubAuth_1 = require("./githubAuth");
72
71
  var logger_1 = require("./logger");
73
72
  var openApiCompat_1 = require("./openApiCompat");
74
73
  var openApiEtag_1 = require("./openApiEtag");
74
+ var index_1 = __importDefault(require("./vendor/wesleytodd-openapi/index"));
75
75
  /**
76
76
  * Fluent API for building Express applications with Terreno framework.
77
77
  *
@@ -300,7 +300,7 @@ var TerrenoApp = /** @class */ (function () {
300
300
  // OpenAPI
301
301
  app.use(openApiCompat_1.openApiCompatMiddleware);
302
302
  app.use(openApiEtag_1.openApiEtagMiddleware);
303
- var oapi = (0, openapi_1.default)({
303
+ var oapi = (0, index_1.default)({
304
304
  info: {
305
305
  description: "Generated docs from an Express api",
306
306
  title: "Express Application",
@@ -0,0 +1,27 @@
1
+ declare function _exports(_routePrefix: any, _doc: any, _opts: any): {
2
+ (req: any, res: any, next: any): void;
3
+ routePrefix: any;
4
+ document: any;
5
+ generateDocument: (baseDocument: any, router: any, basePath: any) => any;
6
+ options: any;
7
+ path(schema?: {}): (req: any, res: any, next: any) => void;
8
+ validPath(schema?: {}, pathOpts?: {}): (req: any, res: any, next: any) => any;
9
+ component(type: any, name: any, description: any): any;
10
+ schema: (name?: any, description?: any) => any;
11
+ response: (name?: any, description?: any) => any;
12
+ parameters: (name?: any, description?: any) => any;
13
+ examples: (name?: any, description?: any) => any;
14
+ requestBodies: (name?: any, description?: any) => any;
15
+ headers: (name?: any, description?: any) => any;
16
+ securitySchemes: (name?: any, description?: any) => any;
17
+ links: (name?: any, description?: any) => any;
18
+ callbacks: (name?: any, description?: any) => any;
19
+ swaggerui(options: any): any[];
20
+ };
21
+ declare namespace _exports {
22
+ export { minimumViableDocument };
23
+ export { defaultRoutePrefix };
24
+ }
25
+ export = _exports;
26
+ import minimumViableDocument = require("./lib/minimum-doc");
27
+ declare const defaultRoutePrefix: "/openapi";
@@ -0,0 +1,176 @@
1
+ // Vendored from https://github.com/wesleytodd/express-openapi (branch: express-5)
2
+ // Package: @wesleytodd/openapi v1.1.0
3
+ // License: ISC (see LICENSE)
4
+ // Vendored to allow local modifications and avoid external dependency drift.
5
+ 'use strict';
6
+ var __assign = (this && this.__assign) || function () {
7
+ __assign = Object.assign || function(t) {
8
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
9
+ s = arguments[i];
10
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
11
+ t[p] = s[p];
12
+ }
13
+ return t;
14
+ };
15
+ return __assign.apply(this, arguments);
16
+ };
17
+ var httpErrors = require('http-errors');
18
+ var Router = require('router');
19
+ var SwaggerParser = require('swagger-parser');
20
+ var ui = require('./lib/ui');
21
+ var makeValidator = require('./lib/validate');
22
+ var _a = require('./lib/layer-schema'), getSchema = _a.get, setSchema = _a.set;
23
+ var minimumViableDocument = require('./lib/minimum-doc');
24
+ var generateDocument = require('./lib/generate-doc');
25
+ var defaultRoutePrefix = '/openapi';
26
+ var YAML = require('yaml');
27
+ module.exports = function ExpressOpenApi(_routePrefix, _doc, _opts) {
28
+ // Acceptable arguments:
29
+ // oapi()
30
+ // oapi('/path')
31
+ // oapi('/path', doc)
32
+ // oapi('/path', doc, opts)
33
+ // oapi(doc)
34
+ // oapi(doc, opts)
35
+ //
36
+ // The below logic is correct, but very hard to reason about
37
+ var routePrefix = _routePrefix || defaultRoutePrefix;
38
+ var doc = _doc || minimumViableDocument;
39
+ var opts = _opts || {};
40
+ if (typeof _routePrefix !== 'string') {
41
+ routePrefix = defaultRoutePrefix;
42
+ doc = _routePrefix || minimumViableDocument;
43
+ opts = _doc || {};
44
+ }
45
+ // We need to route a bit, seems a safe addition
46
+ // to use the express router in an express middleware
47
+ var router = new Router();
48
+ // Fully generate the doc on the first request
49
+ var isFirstRequest = true;
50
+ // Where the magic happens
51
+ var middleware = function OpenApiMiddleware(req, res, next) {
52
+ if (isFirstRequest) {
53
+ middleware.document = generateDocument(middleware.document, req.app._router || req.app.router, opts.basePath);
54
+ isFirstRequest = false;
55
+ }
56
+ router.handle(req, res, next);
57
+ };
58
+ // Expose the current document and prefix
59
+ middleware.routePrefix = routePrefix;
60
+ middleware.document = generateDocument(doc, undefined, opts.basePath);
61
+ middleware.generateDocument = generateDocument;
62
+ middleware.options = opts;
63
+ // Add a path schema to the document
64
+ middleware.path = function (schema) {
65
+ if (schema === void 0) { schema = {}; }
66
+ function schemaMiddleware(req, res, next) {
67
+ next();
68
+ }
69
+ setSchema(schemaMiddleware, schema);
70
+ return schemaMiddleware;
71
+ };
72
+ // Validate path middleware
73
+ middleware.validPath = function (schema, pathOpts) {
74
+ if (schema === void 0) { schema = {}; }
75
+ if (pathOpts === void 0) { pathOpts = {}; }
76
+ var validate;
77
+ function validSchemaMiddleware(req, res, next) {
78
+ if (!validate) {
79
+ validate = makeValidator(middleware, getSchema(validSchemaMiddleware), __assign(__assign({}, pathOpts), opts));
80
+ }
81
+ return validate(req, res, next);
82
+ }
83
+ setSchema(validSchemaMiddleware, schema);
84
+ return validSchemaMiddleware;
85
+ };
86
+ // Component definitions
87
+ middleware.component = function (type, name, description) {
88
+ if (!type) {
89
+ throw new TypeError('Component type is required');
90
+ }
91
+ // Return whole component type
92
+ if (!name && !description) {
93
+ return middleware.document.components && middleware.document.components[type];
94
+ }
95
+ // Return ref to type
96
+ if (name && !description) {
97
+ if (!middleware.document.components || !middleware.document.components[type] || !middleware.document.components[type][name]) {
98
+ throw new Error("Unknown ".concat(type, " ref: ").concat(name));
99
+ }
100
+ return { $ref: "#/components/".concat(type, "/").concat(name) };
101
+ }
102
+ // Set name on parameter if not passed
103
+ if (type === 'parameters') {
104
+ description.name = description.name || name;
105
+ }
106
+ // Define a new component
107
+ middleware.document.components = middleware.document.components || {};
108
+ middleware.document.components[type] = middleware.document.components[type] || {};
109
+ middleware.document.components[type][name] = description;
110
+ return middleware;
111
+ };
112
+ middleware.schema = middleware.component.bind(null, 'schemas');
113
+ middleware.response = middleware.component.bind(null, 'responses');
114
+ middleware.parameters = middleware.component.bind(null, 'parameters');
115
+ middleware.examples = middleware.component.bind(null, 'examples');
116
+ middleware.requestBodies = middleware.component.bind(null, 'requestBodies');
117
+ middleware.headers = middleware.component.bind(null, 'headers');
118
+ middleware.securitySchemes = middleware.component.bind(null, 'securitySchemes');
119
+ middleware.links = middleware.component.bind(null, 'links');
120
+ middleware.callbacks = middleware.component.bind(null, 'callbacks');
121
+ // Expose ui middleware
122
+ middleware.swaggerui = function (options) { return ui.serveSwaggerUI("".concat(routePrefix, ".json"), options); };
123
+ // OpenAPI document as json
124
+ router.get("".concat(routePrefix, ".json"), function (req, res) {
125
+ middleware.document = generateDocument(middleware.document, req.app._router || req.app.router, opts.basePath);
126
+ res.json(middleware.document);
127
+ });
128
+ // OpenAPI document as yaml
129
+ router.get(["".concat(routePrefix, ".yaml"), "".concat(routePrefix, ".yml")], function (req, res) {
130
+ var jsonSpec = generateDocument(middleware.document, req.app._router || req.app.router, opts.basePath);
131
+ var yamlSpec = YAML.stringify(jsonSpec);
132
+ res.type('yaml');
133
+ res.send(yamlSpec);
134
+ });
135
+ router.get("".concat(routePrefix, "/components/:type/:name.json"), function (req, res, next) {
136
+ var _a = req.params, type = _a.type, name = _a.name;
137
+ middleware.document = generateDocument(middleware.document, req.app._router || req.app.router, opts.basePath);
138
+ // No component by that identifer
139
+ if (!middleware.document.components[type] || !middleware.document.components[type][name]) {
140
+ return next(httpErrors(404, "Component does not exist: ".concat(type, "/").concat(name)));
141
+ }
142
+ // Return component
143
+ res.json(middleware.document.components[type][name]);
144
+ });
145
+ // Validate full open api document
146
+ router.get("".concat(routePrefix, "/validate"), function (req, res) {
147
+ middleware.document = generateDocument(middleware.document, req.app._router || req.app.router, opts.basePath);
148
+ SwaggerParser.validate(middleware.document, function (err, api) {
149
+ if (err) {
150
+ return res.json({
151
+ valid: false,
152
+ details: err.details,
153
+ document: middleware.document
154
+ });
155
+ }
156
+ res.json({
157
+ valid: true,
158
+ document: middleware.document
159
+ });
160
+ });
161
+ });
162
+ // Serve up the for exploring the document
163
+ if (opts.htmlui) {
164
+ var ui_1 = opts.htmlui;
165
+ if (!Array.isArray(opts.htmlui)) {
166
+ ui_1 = [opts.htmlui];
167
+ }
168
+ if (ui_1.includes('swagger-ui')) {
169
+ router.get("".concat(routePrefix), function (req, res) { res.redirect("".concat(routePrefix, "/swagger-ui")); });
170
+ router.use("".concat(routePrefix, "/swagger-ui"), middleware.swaggerui);
171
+ }
172
+ }
173
+ return middleware;
174
+ };
175
+ module.exports.minimumViableDocument = minimumViableDocument;
176
+ module.exports.defaultRoutePrefix = defaultRoutePrefix;
@@ -0,0 +1,2 @@
1
+ declare function _exports(jsonObject: object): string;
2
+ export = _exports;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // Vendored from https://github.com/wesleytodd/express-openapi (branch: express-5)
3
+ // License: ISC (see ../LICENSE)
4
+ var YAML = require('yaml');
5
+ /**
6
+ * Converts a json to yaml
7
+ * @param {object} jsonObject
8
+ * @returns {string} yamlString
9
+ */
10
+ module.exports = function (jsonObject) {
11
+ var doc = YAML.stringify(jsonObject);
12
+ return doc;
13
+ };
@@ -0,0 +1,2 @@
1
+ declare function _exports(baseDocument: any, router: any, basePath: any): any;
2
+ export = _exports;