sprint-es 0.0.52 → 0.0.56
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/cjs/cli.cjs +2 -4
- package/dist/cjs/index.cjs +159 -25
- package/dist/cjs/modules/schemas/index.cjs +10 -16
- package/dist/esm/cli.js +2 -4
- package/dist/esm/index.js +137 -25
- package/dist/esm/modules/schemas/index.js +10 -16
- package/dist/types/modules/schemas/index.d.ts.map +1 -1
- package/dist/types/sprint.d.ts +5 -2
- package/dist/types/sprint.d.ts.map +1 -1
- package/dist/types/types.d.ts +24 -0
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +5 -1
package/dist/cjs/cli.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
const child_process = require("child_process");
|
|
4
3
|
const fs = require("fs");
|
|
5
4
|
const crypto = require("crypto");
|
|
6
5
|
const path = require("path");
|
|
6
|
+
const child_process = require("child_process");
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
9
9
|
if (e) {
|
|
@@ -48,9 +48,7 @@ if (command === "--help" || command === "-h") {
|
|
|
48
48
|
function getProjectRoot() {
|
|
49
49
|
let dir = process.cwd();
|
|
50
50
|
while (dir !== path.resolve(dir, "..")) {
|
|
51
|
-
if (fs.existsSync(path.join(dir, "sprint.config.ts")) || fs.existsSync(path.join(dir, "sprint.config.js")))
|
|
52
|
-
return dir;
|
|
53
|
-
}
|
|
51
|
+
if (fs.existsSync(path.join(dir, "sprint.config.ts")) || fs.existsSync(path.join(dir, "sprint.config.js"))) return dir;
|
|
54
52
|
dir = path.resolve(dir, "..");
|
|
55
53
|
}
|
|
56
54
|
return process.cwd();
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
2
24
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
25
|
const express = require("express");
|
|
4
26
|
const fs = require("fs");
|
|
@@ -51,31 +73,103 @@ const limiter = new rateLimit.RateLimiter({
|
|
|
51
73
|
});
|
|
52
74
|
const isDevelopment = isDev;
|
|
53
75
|
const isProduction = isProd;
|
|
76
|
+
async function findProjectRoot(startDir) {
|
|
77
|
+
let currentDir = startDir;
|
|
78
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
79
|
+
const packageJsonPath = path.join(currentDir, "package.json");
|
|
80
|
+
if (fs.existsSync(packageJsonPath)) return currentDir;
|
|
81
|
+
currentDir = path.dirname(currentDir);
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
async function loadSprintConfig() {
|
|
86
|
+
const callerDir = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd();
|
|
87
|
+
const projectRoot = await findProjectRoot(callerDir);
|
|
88
|
+
if (!projectRoot) return null;
|
|
89
|
+
const configFiles = ["sprint.config.ts", "sprint.config.js"];
|
|
90
|
+
for (const configFile of configFiles) {
|
|
91
|
+
const configPath = path.join(projectRoot, configFile);
|
|
92
|
+
if (fs.existsSync(configPath)) {
|
|
93
|
+
try {
|
|
94
|
+
const moduleUrl = url.pathToFileURL(configPath).href;
|
|
95
|
+
const config = await import(moduleUrl);
|
|
96
|
+
return config.default || config;
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.warn(`[Sprint] Failed to load config from ${configPath}:`, err);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
54
104
|
class Sprint {
|
|
55
|
-
constructor({
|
|
56
|
-
port = process.env.PORT
|
|
57
|
-
routesPath = "./routes"
|
|
58
|
-
middlewaresPath = "./middlewares"
|
|
59
|
-
cronjobsPath = "./cronjobs"
|
|
60
|
-
jsonLimit = "50mb"
|
|
61
|
-
urlEncodedLimit = "50mb"
|
|
62
|
-
prefix = ""
|
|
63
|
-
autoListen = true
|
|
64
|
-
} = {}) {
|
|
105
|
+
constructor() {
|
|
106
|
+
this.port = process.env.PORT;
|
|
107
|
+
this.routesPath = "./routes";
|
|
108
|
+
this.middlewaresPath = "./middlewares";
|
|
109
|
+
this.cronjobsPath = "./cronjobs";
|
|
110
|
+
this.jsonLimit = "50mb";
|
|
111
|
+
this.urlEncodedLimit = "50mb";
|
|
112
|
+
this.prefix = "";
|
|
65
113
|
this.loadedMiddlewares = [];
|
|
114
|
+
this.openapi = {
|
|
115
|
+
generateOnBuild: false,
|
|
116
|
+
swaggerUi: {
|
|
117
|
+
enabled: false
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.registeredRoutes = [];
|
|
66
121
|
this.app = express();
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
122
|
+
loadSprintConfig().then((config) => {
|
|
123
|
+
const defaults = {
|
|
124
|
+
port: process.env.PORT,
|
|
125
|
+
routesPath: "./routes",
|
|
126
|
+
middlewaresPath: "./middlewares",
|
|
127
|
+
cronjobsPath: "./cronjobs",
|
|
128
|
+
jsonLimit: "50mb",
|
|
129
|
+
urlEncodedLimit: "50mb",
|
|
130
|
+
prefix: "",
|
|
131
|
+
autoListen: true,
|
|
132
|
+
openapi: {
|
|
133
|
+
generateOnBuild: false,
|
|
134
|
+
swaggerUi: {
|
|
135
|
+
enabled: false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
const finalConfig = { ...defaults, ...config };
|
|
140
|
+
this.port = finalConfig.port;
|
|
141
|
+
this.routesPath = finalConfig.routesPath || "./routes";
|
|
142
|
+
this.middlewaresPath = finalConfig.middlewaresPath || "./middlewares";
|
|
143
|
+
this.cronjobsPath = finalConfig.cronjobsPath || "./cronjobs";
|
|
144
|
+
this.jsonLimit = finalConfig.jsonLimit || "50mb";
|
|
145
|
+
this.urlEncodedLimit = finalConfig.urlEncodedLimit || "50mb";
|
|
146
|
+
this.prefix = finalConfig.prefix ? "/" + finalConfig.prefix.replace(/^\/+|\/+$/g, "") : "";
|
|
147
|
+
this.openapi = {
|
|
148
|
+
generateOnBuild: finalConfig.openapi?.generateOnBuild ?? false,
|
|
149
|
+
swaggerUi: {
|
|
150
|
+
enabled: finalConfig.openapi?.swaggerUi?.enabled ?? false
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
if (this.openapi.generateOnBuild === true) console.log(`[Sprint] ⚠️ openapi.generateOnBuild is enabled but this option makes nothing for now`);
|
|
154
|
+
this.loadDefaults();
|
|
155
|
+
this.loadHealthcheck();
|
|
156
|
+
this.routesLoaded = this.init();
|
|
157
|
+
if (this.openapi.generateOnBuild) {
|
|
158
|
+
this.app.get("/openapi.json", (_, res) => {
|
|
159
|
+
res.json(this.generateOpenAPISpec());
|
|
160
|
+
});
|
|
161
|
+
if (finalConfig.openapi?.swaggerUi?.enabled) {
|
|
162
|
+
import("swagger-ui-express").then((swaggerUi) => {
|
|
163
|
+
this.app.use("/docs", swaggerUi.serve, swaggerUi.setup(void 0, {
|
|
164
|
+
swaggerUrl: "/openapi.json"
|
|
165
|
+
}));
|
|
166
|
+
}).catch(() => {
|
|
167
|
+
console.error(`[Sprint] ⚠️ swagger-ui-express is not installed. Run "npm install swagger-ui-express" to enable Swagger UI.`);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (finalConfig.autoListen) this.routesLoaded.then(() => this.listen());
|
|
172
|
+
});
|
|
79
173
|
}
|
|
80
174
|
async init() {
|
|
81
175
|
const callerDir = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd();
|
|
@@ -224,6 +318,24 @@ class Sprint {
|
|
|
224
318
|
if (routePath.endsWith("/index")) routePath = routePath.slice(0, -6) || "/";
|
|
225
319
|
const fullRoute = this.prefix + (routePath === "/" ? "" : routePath);
|
|
226
320
|
const finalRoute = fullRoute || "/";
|
|
321
|
+
if (this.openapi.generateOnBuild) {
|
|
322
|
+
if (!this.registeredRoutes) this.registeredRoutes = [];
|
|
323
|
+
for (const layer of router.stack) {
|
|
324
|
+
if (!layer.route) continue;
|
|
325
|
+
const route = layer.route;
|
|
326
|
+
for (const routeLayer of route.stack) {
|
|
327
|
+
const schema = routeLayer.handle.__sprintRouteSchema;
|
|
328
|
+
if (!schema) continue;
|
|
329
|
+
const method = (routeLayer.method || "").toUpperCase();
|
|
330
|
+
if (!method) continue;
|
|
331
|
+
this.registeredRoutes.push({
|
|
332
|
+
method,
|
|
333
|
+
path: finalRoute + route.path,
|
|
334
|
+
schema
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
227
339
|
const routeMiddlewares = this.getMiddlewaresForRoute(routePath);
|
|
228
340
|
if (routeMiddlewares.length > 0) {
|
|
229
341
|
this.app.use(finalRoute, ...routeMiddlewares, router);
|
|
@@ -292,6 +404,29 @@ class Sprint {
|
|
|
292
404
|
if (!this.prefix) return routePath;
|
|
293
405
|
return this.prefix + (routePath.startsWith("/") ? routePath : "/" + routePath);
|
|
294
406
|
}
|
|
407
|
+
generateOpenAPISpec() {
|
|
408
|
+
const paths = {};
|
|
409
|
+
for (const route of this.registeredRoutes || []) {
|
|
410
|
+
const method = route.method.toLowerCase();
|
|
411
|
+
if (!paths[route.path]) paths[route.path] = {};
|
|
412
|
+
paths[route.path][method] = {
|
|
413
|
+
summary: "Auto generated by Sprint",
|
|
414
|
+
responses: {
|
|
415
|
+
"200": {
|
|
416
|
+
description: "Success"
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
return {
|
|
422
|
+
openapi: "3.0.0",
|
|
423
|
+
info: {
|
|
424
|
+
title: "Sprint API",
|
|
425
|
+
version: "1.0.0"
|
|
426
|
+
},
|
|
427
|
+
paths
|
|
428
|
+
};
|
|
429
|
+
}
|
|
295
430
|
// HTTP Methods (prefix is applied automatically).
|
|
296
431
|
get(path2, handler) {
|
|
297
432
|
return this.app.get(this.applyPrefix(path2), handler);
|
|
@@ -309,9 +444,7 @@ class Sprint {
|
|
|
309
444
|
return this.app.patch(this.applyPrefix(path2), handler);
|
|
310
445
|
}
|
|
311
446
|
use(pathOrHandler, maybeHandler) {
|
|
312
|
-
if (typeof pathOrHandler === "string" && maybeHandler)
|
|
313
|
-
return this.app.use(this.applyPrefix(pathOrHandler), maybeHandler);
|
|
314
|
-
}
|
|
447
|
+
if (typeof pathOrHandler === "string" && maybeHandler) return this.app.use(this.applyPrefix(pathOrHandler), maybeHandler);
|
|
315
448
|
if (pathOrHandler && typeof pathOrHandler === "object" && "handler" in pathOrHandler) {
|
|
316
449
|
const config = pathOrHandler;
|
|
317
450
|
const handlers = Array.isArray(config.handler) ? config.handler : [config.handler];
|
|
@@ -326,6 +459,7 @@ class Sprint {
|
|
|
326
459
|
let serverStarted = false;
|
|
327
460
|
const tryListen = (port) => {
|
|
328
461
|
triedPorts.push(port);
|
|
462
|
+
this.server = http.createServer(this.app);
|
|
329
463
|
this.server.listen(port, () => {
|
|
330
464
|
serverStarted = true;
|
|
331
465
|
const prefixInfo = this.prefix ? this.prefix : "/";
|
|
@@ -15,31 +15,25 @@ function parseSchema(schema, data) {
|
|
|
15
15
|
return { success: true, data: result.data };
|
|
16
16
|
}
|
|
17
17
|
function defineRouteSchema(schema) {
|
|
18
|
-
|
|
18
|
+
const middleware = (req, res, next) => {
|
|
19
19
|
const errors = [];
|
|
20
|
-
if (schema.body
|
|
20
|
+
if (schema.body) {
|
|
21
21
|
const result = parseSchema(schema.body, req.body);
|
|
22
|
-
if (!result.success) {
|
|
23
|
-
errors.push(...result.errors.map((e) => ({ location: "body", ...e })));
|
|
24
|
-
}
|
|
22
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "body", ...e })));
|
|
25
23
|
}
|
|
26
|
-
if (schema.queryParams
|
|
24
|
+
if (schema.queryParams) {
|
|
27
25
|
const result = parseSchema(schema.queryParams, req.query);
|
|
28
|
-
if (!result.success) {
|
|
29
|
-
errors.push(...result.errors.map((e) => ({ location: "queryParams", ...e })));
|
|
30
|
-
}
|
|
26
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "queryParams", ...e })));
|
|
31
27
|
}
|
|
32
|
-
if (schema.params
|
|
28
|
+
if (schema.params) {
|
|
33
29
|
const result = parseSchema(schema.params, req.params);
|
|
34
|
-
if (!result.success) {
|
|
35
|
-
errors.push(...result.errors.map((e) => ({ location: "params", ...e })));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (errors.length > 0) {
|
|
39
|
-
return res.status(400).json({ error: "Validation failed", details: errors });
|
|
30
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "params", ...e })));
|
|
40
31
|
}
|
|
32
|
+
if (errors.length > 0) return res.status(400).json({ error: "Validation failed", details: errors });
|
|
41
33
|
next();
|
|
42
34
|
};
|
|
35
|
+
middleware.__sprintRouteSchema = schema;
|
|
36
|
+
return middleware;
|
|
43
37
|
}
|
|
44
38
|
Object.defineProperty(exports, "z", {
|
|
45
39
|
enumerable: true,
|
package/dist/esm/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawn } from "child_process";
|
|
3
2
|
import { existsSync } from "fs";
|
|
4
3
|
import * as crypto from "crypto";
|
|
5
4
|
import { join, resolve } from "path";
|
|
5
|
+
import { spawn } from "child_process";
|
|
6
6
|
const args = process.argv.slice(2);
|
|
7
7
|
const command = args[0];
|
|
8
8
|
if (!command) {
|
|
@@ -30,9 +30,7 @@ if (command === "--help" || command === "-h") {
|
|
|
30
30
|
function getProjectRoot() {
|
|
31
31
|
let dir = process.cwd();
|
|
32
32
|
while (dir !== resolve(dir, "..")) {
|
|
33
|
-
if (existsSync(join(dir, "sprint.config.ts")) || existsSync(join(dir, "sprint.config.js")))
|
|
34
|
-
return dir;
|
|
35
|
-
}
|
|
33
|
+
if (existsSync(join(dir, "sprint.config.ts")) || existsSync(join(dir, "sprint.config.js"))) return dir;
|
|
36
34
|
dir = resolve(dir, "..");
|
|
37
35
|
}
|
|
38
36
|
return process.cwd();
|
package/dist/esm/index.js
CHANGED
|
@@ -48,31 +48,103 @@ const limiter = new RateLimiter({
|
|
|
48
48
|
});
|
|
49
49
|
const isDevelopment = isDev;
|
|
50
50
|
const isProduction = isProd;
|
|
51
|
+
async function findProjectRoot(startDir) {
|
|
52
|
+
let currentDir = startDir;
|
|
53
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
54
|
+
const packageJsonPath = path.join(currentDir, "package.json");
|
|
55
|
+
if (fs.existsSync(packageJsonPath)) return currentDir;
|
|
56
|
+
currentDir = path.dirname(currentDir);
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
async function loadSprintConfig() {
|
|
61
|
+
const callerDir = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd();
|
|
62
|
+
const projectRoot = await findProjectRoot(callerDir);
|
|
63
|
+
if (!projectRoot) return null;
|
|
64
|
+
const configFiles = ["sprint.config.ts", "sprint.config.js"];
|
|
65
|
+
for (const configFile of configFiles) {
|
|
66
|
+
const configPath = path.join(projectRoot, configFile);
|
|
67
|
+
if (fs.existsSync(configPath)) {
|
|
68
|
+
try {
|
|
69
|
+
const moduleUrl = pathToFileURL(configPath).href;
|
|
70
|
+
const config = await import(moduleUrl);
|
|
71
|
+
return config.default || config;
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.warn(`[Sprint] Failed to load config from ${configPath}:`, err);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
51
79
|
class Sprint {
|
|
52
|
-
constructor({
|
|
53
|
-
port = process.env.PORT
|
|
54
|
-
routesPath = "./routes"
|
|
55
|
-
middlewaresPath = "./middlewares"
|
|
56
|
-
cronjobsPath = "./cronjobs"
|
|
57
|
-
jsonLimit = "50mb"
|
|
58
|
-
urlEncodedLimit = "50mb"
|
|
59
|
-
prefix = ""
|
|
60
|
-
autoListen = true
|
|
61
|
-
} = {}) {
|
|
80
|
+
constructor() {
|
|
81
|
+
this.port = process.env.PORT;
|
|
82
|
+
this.routesPath = "./routes";
|
|
83
|
+
this.middlewaresPath = "./middlewares";
|
|
84
|
+
this.cronjobsPath = "./cronjobs";
|
|
85
|
+
this.jsonLimit = "50mb";
|
|
86
|
+
this.urlEncodedLimit = "50mb";
|
|
87
|
+
this.prefix = "";
|
|
62
88
|
this.loadedMiddlewares = [];
|
|
89
|
+
this.openapi = {
|
|
90
|
+
generateOnBuild: false,
|
|
91
|
+
swaggerUi: {
|
|
92
|
+
enabled: false
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
this.registeredRoutes = [];
|
|
63
96
|
this.app = express();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
97
|
+
loadSprintConfig().then((config) => {
|
|
98
|
+
const defaults = {
|
|
99
|
+
port: process.env.PORT,
|
|
100
|
+
routesPath: "./routes",
|
|
101
|
+
middlewaresPath: "./middlewares",
|
|
102
|
+
cronjobsPath: "./cronjobs",
|
|
103
|
+
jsonLimit: "50mb",
|
|
104
|
+
urlEncodedLimit: "50mb",
|
|
105
|
+
prefix: "",
|
|
106
|
+
autoListen: true,
|
|
107
|
+
openapi: {
|
|
108
|
+
generateOnBuild: false,
|
|
109
|
+
swaggerUi: {
|
|
110
|
+
enabled: false
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const finalConfig = { ...defaults, ...config };
|
|
115
|
+
this.port = finalConfig.port;
|
|
116
|
+
this.routesPath = finalConfig.routesPath || "./routes";
|
|
117
|
+
this.middlewaresPath = finalConfig.middlewaresPath || "./middlewares";
|
|
118
|
+
this.cronjobsPath = finalConfig.cronjobsPath || "./cronjobs";
|
|
119
|
+
this.jsonLimit = finalConfig.jsonLimit || "50mb";
|
|
120
|
+
this.urlEncodedLimit = finalConfig.urlEncodedLimit || "50mb";
|
|
121
|
+
this.prefix = finalConfig.prefix ? "/" + finalConfig.prefix.replace(/^\/+|\/+$/g, "") : "";
|
|
122
|
+
this.openapi = {
|
|
123
|
+
generateOnBuild: finalConfig.openapi?.generateOnBuild ?? false,
|
|
124
|
+
swaggerUi: {
|
|
125
|
+
enabled: finalConfig.openapi?.swaggerUi?.enabled ?? false
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
if (this.openapi.generateOnBuild === true) console.log(`[Sprint] ⚠️ openapi.generateOnBuild is enabled but this option makes nothing for now`);
|
|
129
|
+
this.loadDefaults();
|
|
130
|
+
this.loadHealthcheck();
|
|
131
|
+
this.routesLoaded = this.init();
|
|
132
|
+
if (this.openapi.generateOnBuild) {
|
|
133
|
+
this.app.get("/openapi.json", (_, res) => {
|
|
134
|
+
res.json(this.generateOpenAPISpec());
|
|
135
|
+
});
|
|
136
|
+
if (finalConfig.openapi?.swaggerUi?.enabled) {
|
|
137
|
+
import("swagger-ui-express").then((swaggerUi) => {
|
|
138
|
+
this.app.use("/docs", swaggerUi.serve, swaggerUi.setup(void 0, {
|
|
139
|
+
swaggerUrl: "/openapi.json"
|
|
140
|
+
}));
|
|
141
|
+
}).catch(() => {
|
|
142
|
+
console.error(`[Sprint] ⚠️ swagger-ui-express is not installed. Run "npm install swagger-ui-express" to enable Swagger UI.`);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (finalConfig.autoListen) this.routesLoaded.then(() => this.listen());
|
|
147
|
+
});
|
|
76
148
|
}
|
|
77
149
|
async init() {
|
|
78
150
|
const callerDir = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd();
|
|
@@ -221,6 +293,24 @@ class Sprint {
|
|
|
221
293
|
if (routePath.endsWith("/index")) routePath = routePath.slice(0, -6) || "/";
|
|
222
294
|
const fullRoute = this.prefix + (routePath === "/" ? "" : routePath);
|
|
223
295
|
const finalRoute = fullRoute || "/";
|
|
296
|
+
if (this.openapi.generateOnBuild) {
|
|
297
|
+
if (!this.registeredRoutes) this.registeredRoutes = [];
|
|
298
|
+
for (const layer of router.stack) {
|
|
299
|
+
if (!layer.route) continue;
|
|
300
|
+
const route = layer.route;
|
|
301
|
+
for (const routeLayer of route.stack) {
|
|
302
|
+
const schema = routeLayer.handle.__sprintRouteSchema;
|
|
303
|
+
if (!schema) continue;
|
|
304
|
+
const method = (routeLayer.method || "").toUpperCase();
|
|
305
|
+
if (!method) continue;
|
|
306
|
+
this.registeredRoutes.push({
|
|
307
|
+
method,
|
|
308
|
+
path: finalRoute + route.path,
|
|
309
|
+
schema
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
224
314
|
const routeMiddlewares = this.getMiddlewaresForRoute(routePath);
|
|
225
315
|
if (routeMiddlewares.length > 0) {
|
|
226
316
|
this.app.use(finalRoute, ...routeMiddlewares, router);
|
|
@@ -289,6 +379,29 @@ class Sprint {
|
|
|
289
379
|
if (!this.prefix) return routePath;
|
|
290
380
|
return this.prefix + (routePath.startsWith("/") ? routePath : "/" + routePath);
|
|
291
381
|
}
|
|
382
|
+
generateOpenAPISpec() {
|
|
383
|
+
const paths = {};
|
|
384
|
+
for (const route of this.registeredRoutes || []) {
|
|
385
|
+
const method = route.method.toLowerCase();
|
|
386
|
+
if (!paths[route.path]) paths[route.path] = {};
|
|
387
|
+
paths[route.path][method] = {
|
|
388
|
+
summary: "Auto generated by Sprint",
|
|
389
|
+
responses: {
|
|
390
|
+
"200": {
|
|
391
|
+
description: "Success"
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
return {
|
|
397
|
+
openapi: "3.0.0",
|
|
398
|
+
info: {
|
|
399
|
+
title: "Sprint API",
|
|
400
|
+
version: "1.0.0"
|
|
401
|
+
},
|
|
402
|
+
paths
|
|
403
|
+
};
|
|
404
|
+
}
|
|
292
405
|
// HTTP Methods (prefix is applied automatically).
|
|
293
406
|
get(path2, handler) {
|
|
294
407
|
return this.app.get(this.applyPrefix(path2), handler);
|
|
@@ -306,9 +419,7 @@ class Sprint {
|
|
|
306
419
|
return this.app.patch(this.applyPrefix(path2), handler);
|
|
307
420
|
}
|
|
308
421
|
use(pathOrHandler, maybeHandler) {
|
|
309
|
-
if (typeof pathOrHandler === "string" && maybeHandler)
|
|
310
|
-
return this.app.use(this.applyPrefix(pathOrHandler), maybeHandler);
|
|
311
|
-
}
|
|
422
|
+
if (typeof pathOrHandler === "string" && maybeHandler) return this.app.use(this.applyPrefix(pathOrHandler), maybeHandler);
|
|
312
423
|
if (pathOrHandler && typeof pathOrHandler === "object" && "handler" in pathOrHandler) {
|
|
313
424
|
const config = pathOrHandler;
|
|
314
425
|
const handlers = Array.isArray(config.handler) ? config.handler : [config.handler];
|
|
@@ -323,6 +434,7 @@ class Sprint {
|
|
|
323
434
|
let serverStarted = false;
|
|
324
435
|
const tryListen = (port) => {
|
|
325
436
|
triedPorts.push(port);
|
|
437
|
+
this.server = http.createServer(this.app);
|
|
326
438
|
this.server.listen(port, () => {
|
|
327
439
|
serverStarted = true;
|
|
328
440
|
const prefixInfo = this.prefix ? this.prefix : "/";
|
|
@@ -13,31 +13,25 @@ function parseSchema(schema, data) {
|
|
|
13
13
|
return { success: true, data: result.data };
|
|
14
14
|
}
|
|
15
15
|
function defineRouteSchema(schema) {
|
|
16
|
-
|
|
16
|
+
const middleware = (req, res, next) => {
|
|
17
17
|
const errors = [];
|
|
18
|
-
if (schema.body
|
|
18
|
+
if (schema.body) {
|
|
19
19
|
const result = parseSchema(schema.body, req.body);
|
|
20
|
-
if (!result.success) {
|
|
21
|
-
errors.push(...result.errors.map((e) => ({ location: "body", ...e })));
|
|
22
|
-
}
|
|
20
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "body", ...e })));
|
|
23
21
|
}
|
|
24
|
-
if (schema.queryParams
|
|
22
|
+
if (schema.queryParams) {
|
|
25
23
|
const result = parseSchema(schema.queryParams, req.query);
|
|
26
|
-
if (!result.success) {
|
|
27
|
-
errors.push(...result.errors.map((e) => ({ location: "queryParams", ...e })));
|
|
28
|
-
}
|
|
24
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "queryParams", ...e })));
|
|
29
25
|
}
|
|
30
|
-
if (schema.params
|
|
26
|
+
if (schema.params) {
|
|
31
27
|
const result = parseSchema(schema.params, req.params);
|
|
32
|
-
if (!result.success) {
|
|
33
|
-
errors.push(...result.errors.map((e) => ({ location: "params", ...e })));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (errors.length > 0) {
|
|
37
|
-
return res.status(400).json({ error: "Validation failed", details: errors });
|
|
28
|
+
if (!result.success) errors.push(...result.errors.map((e) => ({ location: "params", ...e })));
|
|
38
29
|
}
|
|
30
|
+
if (errors.length > 0) return res.status(400).json({ error: "Validation failed", details: errors });
|
|
39
31
|
next();
|
|
40
32
|
};
|
|
33
|
+
middleware.__sprintRouteSchema = schema;
|
|
34
|
+
return middleware;
|
|
41
35
|
}
|
|
42
36
|
export {
|
|
43
37
|
defineRouteSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,SAAS,IAAI,aAAa,EAAE,UAAU,EAAY,MAAM,KAAK,CAAC;AAE1E,OAAO,EAAE,CAAC,EAAE,CAAC;AAEb,MAAM,WAAW,kBAAkB;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;CAChD;AAqBD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,kBAAkB,EAAE,MAAM,EAAE,CAAC,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,SAAS,IAAI,aAAa,EAAE,UAAU,EAAY,MAAM,KAAK,CAAC;AAE1E,OAAO,EAAE,CAAC,EAAE,CAAC;AAEb,MAAM,WAAW,kBAAkB;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;CAChD;AAqBD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,kBAAkB,EAAE,MAAM,EAAE,CAAC,GAAG,cAAc,CA4BzF;AAED,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/types/sprint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Handler,
|
|
1
|
+
import { Handler, MiddlewareConfig } from './types';
|
|
2
2
|
import { default as express, Application } from 'express';
|
|
3
3
|
export declare const isDevelopment: boolean;
|
|
4
4
|
export declare const isProduction: boolean;
|
|
@@ -14,7 +14,9 @@ export declare class Sprint {
|
|
|
14
14
|
private routesLoaded;
|
|
15
15
|
private server;
|
|
16
16
|
private loadedMiddlewares;
|
|
17
|
-
|
|
17
|
+
private openapi;
|
|
18
|
+
private registeredRoutes;
|
|
19
|
+
constructor();
|
|
18
20
|
private init;
|
|
19
21
|
private loadDefaults;
|
|
20
22
|
/**
|
|
@@ -31,6 +33,7 @@ export declare class Sprint {
|
|
|
31
33
|
private loadNotFound;
|
|
32
34
|
/** Applies prefix to a path */
|
|
33
35
|
private applyPrefix;
|
|
36
|
+
private generateOpenAPISpec;
|
|
34
37
|
get(path: string, handler: Handler): express.Application;
|
|
35
38
|
post(path: string, handler: Handler): express.Application;
|
|
36
39
|
put(path: string, handler: Handler): express.Application;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sprint.d.ts","sourceRoot":"","sources":["../../src/sprint.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"sprint.d.ts","sourceRoot":"","sources":["../../src/sprint.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAA+B,gBAAgB,EAAoB,MAAM,SAAS,CAAC;AACnG,OAAO,OAAO,EAAE,EAAE,WAAW,EAAoD,MAAM,SAAS,CAAC;AAejG,eAAO,MAAM,aAAa,SAAQ,CAAC;AACnC,eAAO,MAAM,YAAY,SAAS,CAAC;AAoCnC,qBAAa,MAAM;IACR,GAAG,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,IAAI,CAAwD;IACpE,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,OAAO,CAUb;IACF,OAAO,CAAC,gBAAgB,CAIhB;;YAkEM,IAAI;IA+BlB,OAAO,CAAC,YAAY;IAiDpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;YACW,eAAe;IAgC7B,OAAO,CAAC,eAAe;YAcT,UAAU;YA2EV,YAAY;IAmB1B,OAAO,CAAC,YAAY;IAgCpB,+BAA+B;IAC/B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,mBAAmB;IA6BpB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAClC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAClC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACrC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACpC,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,gBAAgB,EAAE,YAAY,CAAC,EAAE,OAAO;IAYlF,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;CAwDzC"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -67,6 +67,30 @@ export interface SprintOptions {
|
|
|
67
67
|
prefix?: string;
|
|
68
68
|
/** Auto-start the server. Default: true */
|
|
69
69
|
autoListen?: boolean;
|
|
70
|
+
openapi?: {
|
|
71
|
+
enabled?: boolean;
|
|
72
|
+
generateOnBuild?: boolean;
|
|
73
|
+
swaggerUi?: {
|
|
74
|
+
enabled?: boolean;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export interface SprintConfig {
|
|
79
|
+
port?: string | number | null;
|
|
80
|
+
routesPath?: string;
|
|
81
|
+
middlewaresPath?: string;
|
|
82
|
+
cronjobsPath?: string;
|
|
83
|
+
jsonLimit?: string;
|
|
84
|
+
urlEncodedLimit?: string;
|
|
85
|
+
prefix?: string;
|
|
86
|
+
autoListen?: boolean;
|
|
87
|
+
openapi?: {
|
|
88
|
+
enabled?: boolean;
|
|
89
|
+
generateOnBuild?: boolean;
|
|
90
|
+
swaggerUi?: {
|
|
91
|
+
enabled?: boolean;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
70
94
|
}
|
|
71
95
|
export type { NextFunction } from 'express';
|
|
72
96
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE1E,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAEpG,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,GAAG,CAAC;AAE/E,MAAM,MAAM,mBAAmB,GACzB,SAAS,MAAM,EAAE,GACjB,WAAW,MAAM,EAAE,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC1B,gBAAgB,EAAE,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,KAAK,MAAM,GAAG,SAAS,CAAC;CACnG;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEtC,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,OAAO,CAAC;QACd,UAAU,OAAO;YACb,MAAM,EAAE,aAAa,CAAC;YAEtB,MAAM,EAAE,GAAG,CAAC;SACf;KACJ;CACJ;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,oFAAoF;IACpF,OAAO,EAAE,cAAc,GAAG,mBAAmB,GAAG,CAAC,cAAc,GAAG,mBAAmB,CAAC,EAAE,CAAC;IACzF;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprint-es",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.56",
|
|
4
4
|
"description": "Sprint - Quickly API",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
"@types/node": "^22.18.7",
|
|
104
104
|
"@types/node-cron": "^3.0.11",
|
|
105
105
|
"@types/serve-favicon": "^2.5.7",
|
|
106
|
+
"@types/swagger-ui-express": "^4.1.8",
|
|
106
107
|
"jest": "^30.1.3",
|
|
107
108
|
"rimraf": "^6.0.1",
|
|
108
109
|
"ts-jest": "^29.4.4",
|
|
@@ -111,6 +112,9 @@
|
|
|
111
112
|
"vite": "^6.4.1",
|
|
112
113
|
"vite-plugin-dts": "^4.5.4"
|
|
113
114
|
},
|
|
115
|
+
"optionalDependencies": {
|
|
116
|
+
"swagger-ui-express": "^5.0.1"
|
|
117
|
+
},
|
|
114
118
|
"prettier": {
|
|
115
119
|
"tabWidth": 4,
|
|
116
120
|
"useTabs": false
|