sprint-es 0.0.62 → 0.0.65

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.
@@ -167,12 +167,15 @@ class Sprint {
167
167
  res.json(this.generateOpenAPISpec());
168
168
  });
169
169
  if (this.openapi.swaggerUi.enabled) {
170
+ console.log(`[Sprint] Loading Swagger UI...`);
170
171
  import("swagger-ui-express").then((swaggerUi) => {
172
+ console.log(`[Sprint] Swagger UI imported successfully`);
171
173
  this.app.use("/swagger", swaggerUi.serve, swaggerUi.setup(void 0, {
172
174
  swaggerUrl: "/openapi.json"
173
175
  }));
174
- }).catch(() => {
175
- console.error(`[Sprint] ⚠️ swagger-ui-express is not installed. Run "npm install swagger-ui-express" to enable Swagger UI.`);
176
+ console.log(`[Sprint] Swagger UI mounted at /swagger`);
177
+ }).catch((err) => {
178
+ console.error(`[Sprint] ⚠️ swagger-ui-express error:`, err);
176
179
  });
177
180
  }
178
181
  }
@@ -181,7 +184,7 @@ class Sprint {
181
184
  });
182
185
  }
183
186
  async init() {
184
- const callerDir = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd();
187
+ const callerDir = process.cwd();
185
188
  try {
186
189
  const middlewaresCandidate = path.isAbsolute(this.middlewaresPath) ? this.middlewaresPath : path.join(callerDir, this.middlewaresPath);
187
190
  if (fs.existsSync(middlewaresCandidate) && fs.statSync(middlewaresCandidate).isDirectory()) await this.loadMiddlewares(middlewaresCandidate);
@@ -191,8 +194,11 @@ class Sprint {
191
194
  }
192
195
  try {
193
196
  const routesCandidate = path.isAbsolute(this.routesPath) ? this.routesPath : path.join(callerDir, this.routesPath);
194
- if (fs.existsSync(routesCandidate) && fs.statSync(routesCandidate).isDirectory()) await this.loadRoutes(routesCandidate);
195
- else console.log(`[Sprint] Routes folder not found at: ${routesCandidate}, skipping route loading.`);
197
+ console.log(`[Sprint] Looking for routes at: ${routesCandidate}`);
198
+ if (fs.existsSync(routesCandidate) && fs.statSync(routesCandidate).isDirectory()) {
199
+ console.log(`[Sprint] Routes directory found, loading...`);
200
+ await this.loadRoutes(routesCandidate);
201
+ } else console.log(`[Sprint] Routes folder not found at: ${routesCandidate}, skipping route loading.`);
196
202
  } catch (err) {
197
203
  console.error("[Sprint] Failed to load routes:", err);
198
204
  }
@@ -333,17 +339,24 @@ class Sprint {
333
339
  if (!layer.route) continue;
334
340
  const route = layer.route;
335
341
  for (const routeLayer of route.stack) {
336
- const schema = routeLayer.handle.__sprintRouteSchema;
337
- if (!schema) continue;
338
- const method = (routeLayer.method || "").toUpperCase();
339
- if (!method) continue;
340
- this.registeredRoutes.push({
341
- method,
342
- path: finalRoute + route.path,
343
- schema
344
- });
342
+ const handlers = Array.isArray(routeLayer.handle) ? routeLayer.handle : [routeLayer.handle];
343
+ for (const handler of handlers) {
344
+ const schema = handler.__sprintRouteSchema;
345
+ if (schema) {
346
+ const method = (routeLayer.method || "").toUpperCase();
347
+ if (method) {
348
+ this.registeredRoutes.push({
349
+ method,
350
+ path: finalRoute + route.path,
351
+ schema
352
+ });
353
+ }
354
+ break;
355
+ }
356
+ }
345
357
  }
346
358
  }
359
+ console.log(`[Sprint] Registered routes for OpenAPI:`, this.registeredRoutes);
347
360
  }
348
361
  const routeMiddlewares = this.getMiddlewaresForRoute(routePath);
349
362
  if (routeMiddlewares.length > 0) {
@@ -415,10 +428,16 @@ class Sprint {
415
428
  }
416
429
  generateOpenAPISpec() {
417
430
  const paths = {};
431
+ let zod;
432
+ try {
433
+ zod = require("zod");
434
+ } catch (e) {
435
+ console.warn("[Sprint] Zod not available for OpenAPI schema generation");
436
+ }
418
437
  for (const route of this.registeredRoutes || []) {
419
438
  const method = route.method.toLowerCase();
420
439
  if (!paths[route.path]) paths[route.path] = {};
421
- paths[route.path][method] = {
440
+ const routeSpec = {
422
441
  summary: "Auto generated by Sprint",
423
442
  responses: {
424
443
  "200": {
@@ -426,6 +445,36 @@ class Sprint {
426
445
  }
427
446
  }
428
447
  };
448
+ if (route.schema?.body && zod) {
449
+ try {
450
+ routeSpec.requestBody = {
451
+ content: {
452
+ "application/json": {
453
+ schema: route.schema.body.schema || route.schema.body._def?.schema?.toJSON?.() || {}
454
+ }
455
+ }
456
+ };
457
+ } catch (e) {
458
+ }
459
+ }
460
+ if (route.schema?.queryParams && zod) {
461
+ try {
462
+ routeSpec.parameters = [];
463
+ const querySchema = route.schema.queryParams.schema || route.schema.queryParams._def?.schema;
464
+ if (querySchema?.shape) {
465
+ for (const [key, value] of Object.entries(querySchema.shape)) {
466
+ routeSpec.parameters.push({
467
+ name: key,
468
+ in: "query",
469
+ required: !value.isOptional?.(),
470
+ schema: value._def?.typeName ? { type: "string" } : {}
471
+ });
472
+ }
473
+ }
474
+ } catch (e) {
475
+ }
476
+ }
477
+ paths[route.path][method] = routeSpec;
429
478
  }
430
479
  return {
431
480
  openapi: "3.0.0",
package/dist/esm/index.js CHANGED
@@ -142,12 +142,15 @@ class Sprint {
142
142
  res.json(this.generateOpenAPISpec());
143
143
  });
144
144
  if (this.openapi.swaggerUi.enabled) {
145
+ console.log(`[Sprint] Loading Swagger UI...`);
145
146
  import("swagger-ui-express").then((swaggerUi) => {
147
+ console.log(`[Sprint] Swagger UI imported successfully`);
146
148
  this.app.use("/swagger", swaggerUi.serve, swaggerUi.setup(void 0, {
147
149
  swaggerUrl: "/openapi.json"
148
150
  }));
149
- }).catch(() => {
150
- console.error(`[Sprint] ⚠️ swagger-ui-express is not installed. Run "npm install swagger-ui-express" to enable Swagger UI.`);
151
+ console.log(`[Sprint] Swagger UI mounted at /swagger`);
152
+ }).catch((err) => {
153
+ console.error(`[Sprint] ⚠️ swagger-ui-express error:`, err);
151
154
  });
152
155
  }
153
156
  }
@@ -156,7 +159,7 @@ class Sprint {
156
159
  });
157
160
  }
158
161
  async init() {
159
- const callerDir = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd();
162
+ const callerDir = process.cwd();
160
163
  try {
161
164
  const middlewaresCandidate = path.isAbsolute(this.middlewaresPath) ? this.middlewaresPath : path.join(callerDir, this.middlewaresPath);
162
165
  if (fs.existsSync(middlewaresCandidate) && fs.statSync(middlewaresCandidate).isDirectory()) await this.loadMiddlewares(middlewaresCandidate);
@@ -166,8 +169,11 @@ class Sprint {
166
169
  }
167
170
  try {
168
171
  const routesCandidate = path.isAbsolute(this.routesPath) ? this.routesPath : path.join(callerDir, this.routesPath);
169
- if (fs.existsSync(routesCandidate) && fs.statSync(routesCandidate).isDirectory()) await this.loadRoutes(routesCandidate);
170
- else console.log(`[Sprint] Routes folder not found at: ${routesCandidate}, skipping route loading.`);
172
+ console.log(`[Sprint] Looking for routes at: ${routesCandidate}`);
173
+ if (fs.existsSync(routesCandidate) && fs.statSync(routesCandidate).isDirectory()) {
174
+ console.log(`[Sprint] Routes directory found, loading...`);
175
+ await this.loadRoutes(routesCandidate);
176
+ } else console.log(`[Sprint] Routes folder not found at: ${routesCandidate}, skipping route loading.`);
171
177
  } catch (err) {
172
178
  console.error("[Sprint] Failed to load routes:", err);
173
179
  }
@@ -308,17 +314,24 @@ class Sprint {
308
314
  if (!layer.route) continue;
309
315
  const route = layer.route;
310
316
  for (const routeLayer of route.stack) {
311
- const schema = routeLayer.handle.__sprintRouteSchema;
312
- if (!schema) continue;
313
- const method = (routeLayer.method || "").toUpperCase();
314
- if (!method) continue;
315
- this.registeredRoutes.push({
316
- method,
317
- path: finalRoute + route.path,
318
- schema
319
- });
317
+ const handlers = Array.isArray(routeLayer.handle) ? routeLayer.handle : [routeLayer.handle];
318
+ for (const handler of handlers) {
319
+ const schema = handler.__sprintRouteSchema;
320
+ if (schema) {
321
+ const method = (routeLayer.method || "").toUpperCase();
322
+ if (method) {
323
+ this.registeredRoutes.push({
324
+ method,
325
+ path: finalRoute + route.path,
326
+ schema
327
+ });
328
+ }
329
+ break;
330
+ }
331
+ }
320
332
  }
321
333
  }
334
+ console.log(`[Sprint] Registered routes for OpenAPI:`, this.registeredRoutes);
322
335
  }
323
336
  const routeMiddlewares = this.getMiddlewaresForRoute(routePath);
324
337
  if (routeMiddlewares.length > 0) {
@@ -390,10 +403,16 @@ class Sprint {
390
403
  }
391
404
  generateOpenAPISpec() {
392
405
  const paths = {};
406
+ let zod;
407
+ try {
408
+ zod = require("zod");
409
+ } catch (e) {
410
+ console.warn("[Sprint] Zod not available for OpenAPI schema generation");
411
+ }
393
412
  for (const route of this.registeredRoutes || []) {
394
413
  const method = route.method.toLowerCase();
395
414
  if (!paths[route.path]) paths[route.path] = {};
396
- paths[route.path][method] = {
415
+ const routeSpec = {
397
416
  summary: "Auto generated by Sprint",
398
417
  responses: {
399
418
  "200": {
@@ -401,6 +420,36 @@ class Sprint {
401
420
  }
402
421
  }
403
422
  };
423
+ if (route.schema?.body && zod) {
424
+ try {
425
+ routeSpec.requestBody = {
426
+ content: {
427
+ "application/json": {
428
+ schema: route.schema.body.schema || route.schema.body._def?.schema?.toJSON?.() || {}
429
+ }
430
+ }
431
+ };
432
+ } catch (e) {
433
+ }
434
+ }
435
+ if (route.schema?.queryParams && zod) {
436
+ try {
437
+ routeSpec.parameters = [];
438
+ const querySchema = route.schema.queryParams.schema || route.schema.queryParams._def?.schema;
439
+ if (querySchema?.shape) {
440
+ for (const [key, value] of Object.entries(querySchema.shape)) {
441
+ routeSpec.parameters.push({
442
+ name: key,
443
+ in: "query",
444
+ required: !value.isOptional?.(),
445
+ schema: value._def?.typeName ? { type: "string" } : {}
446
+ });
447
+ }
448
+ }
449
+ } catch (e) {
450
+ }
451
+ }
452
+ paths[route.path][method] = routeSpec;
404
453
  }
405
454
  return {
406
455
  openapi: "3.0.0",
@@ -1 +1 @@
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;AAwCnC,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;;YAoEM,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;CA0DzC"}
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;AAwCnC,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;;YAuEM,IAAI;IAkClB,OAAO,CAAC,YAAY;IAiDpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;YACW,eAAe;IAgC7B,OAAO,CAAC,eAAe;YAcT,UAAU;YAoFV,YAAY;IAmB1B,OAAO,CAAC,YAAY;IAgCpB,+BAA+B;IAC/B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,mBAAmB;IAyEpB,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;CA0DzC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprint-es",
3
- "version": "0.0.62",
3
+ "version": "0.0.65",
4
4
  "description": "Sprint - Quickly API",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",