powr-sdk-api 1.0.0

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/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # PowrStack API Core Library
2
+
3
+ A shared library for Express API projects in the PowrStack ecosystem. This library provides common middleware and utilities for error handling, response formatting, logging, and Swagger documentation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install powr-sdk-api
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - Error handling middleware with `APIError` class
14
+ - Response formatting middleware
15
+ - Request/Response logging middleware
16
+ - Swagger documentation setup
17
+ - Async handler utility
18
+
19
+ ## Usage
20
+
21
+ ### Basic Setup
22
+
23
+ ```javascript
24
+ const express = require('express');
25
+ const {
26
+ errorHandler,
27
+ responseHandler,
28
+ logger,
29
+ createSwaggerSpec
30
+ } = require('powr-sdk-api');
31
+
32
+ const app = express();
33
+
34
+ // Apply middleware
35
+ app.use(logger);
36
+ app.use(responseHandler);
37
+
38
+ // Setup Swagger
39
+ const swaggerSpec = createSwaggerSpec({
40
+ title: 'Your API',
41
+ version: '1.0.0',
42
+ description: 'Your API description',
43
+ serverUrl: 'http://localhost:3000'
44
+ });
45
+
46
+ // Apply error handler last
47
+ app.use(errorHandler);
48
+ ```
49
+
50
+ ### Error Handling
51
+
52
+ ```javascript
53
+ const { APIError, asyncHandler } = require('powr-sdk-api');
54
+
55
+ // In your route handler
56
+ app.get('/users/:id', asyncHandler(async (req, res) => {
57
+ const user = await User.findById(req.params.id);
58
+ if (!user) {
59
+ throw new APIError('User not found', 404);
60
+ }
61
+ res.success(user);
62
+ }));
63
+ ```
64
+
65
+ ### Response Formatting
66
+
67
+ ```javascript
68
+ // Success response
69
+ res.success(data, 'Operation successful', 200);
70
+
71
+ // Error response
72
+ res.error('Something went wrong', 500, { details: 'Error details' });
73
+ ```
74
+
75
+ ### Swagger Documentation
76
+
77
+ ```javascript
78
+ const swaggerUi = require('swagger-ui-express');
79
+ const { createSwaggerSpec } = require('powr-sdk-api');
80
+
81
+ const swaggerSpec = createSwaggerSpec({
82
+ title: 'Your API',
83
+ version: '1.0.0',
84
+ description: 'Your API description',
85
+ serverUrl: 'http://localhost:3000'
86
+ });
87
+
88
+ app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
89
+ ```
90
+
91
+ ## API Reference
92
+
93
+ ### Error Handling
94
+
95
+ - `APIError`: Custom error class for API errors
96
+ - `asyncHandler`: Wrapper for async route handlers
97
+ - `errorHandler`: Global error handling middleware
98
+
99
+ ### Response Formatting
100
+
101
+ - `responseHandler`: Middleware for standardizing API responses
102
+ - `res.success()`: Send a success response
103
+ - `res.error()`: Send an error response
104
+
105
+ ### Logging
106
+
107
+ - `logger`: Middleware for logging requests and responses
108
+
109
+ ### Swagger
110
+
111
+ - `createSwaggerSpec`: Function to create Swagger specification
112
+
113
+ ## License
114
+
115
+ ISC
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * PowrStack API Core Library
5
+ * A shared library for Express API projects
6
+ */
7
+
8
+ const errorMiddleware = require('./middleware/error');
9
+ const responseMiddleware = require('./middleware/response');
10
+ const loggerMiddleware = require('./middleware/logger');
11
+ const createSwaggerSpec = require('./swagger');
12
+ module.exports = {
13
+ // Error handling
14
+ APIError: errorMiddleware.APIError,
15
+ asyncHandler: errorMiddleware.asyncHandler,
16
+ errorHandler: errorMiddleware.errorHandler,
17
+ // Response formatting
18
+ responseHandler: responseMiddleware,
19
+ // Logging
20
+ logger: loggerMiddleware,
21
+ // Swagger
22
+ createSwaggerSpec
23
+ };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Error handling middleware for Express applications
5
+ */
6
+
7
+ class APIError extends Error {
8
+ constructor(message, statusCode = 500, details = null) {
9
+ super(message);
10
+ this.statusCode = statusCode;
11
+ this.details = details;
12
+ this.name = 'APIError';
13
+ }
14
+ }
15
+ const asyncHandler = fn => (req, res, next) => {
16
+ Promise.resolve(fn(req, res, next)).catch(next);
17
+ };
18
+ const errorHandler = (err, req, res, next) => {
19
+ console.error('Error:', {
20
+ message: err.message,
21
+ stack: err.stack,
22
+ details: err.details
23
+ });
24
+ const statusCode = err.statusCode || 500;
25
+ const message = err.message || 'Internal Server Error';
26
+ res.status(statusCode).json({
27
+ success: false,
28
+ message,
29
+ details: err.details
30
+ });
31
+ };
32
+ module.exports = {
33
+ APIError,
34
+ asyncHandler,
35
+ errorHandler
36
+ };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Logging middleware for Express applications
5
+ */
6
+
7
+ const logger = (req, res, next) => {
8
+ // Log request
9
+ console.log('Request:', {
10
+ timestamp: new Date().toISOString(),
11
+ method: req.method,
12
+ url: req.url,
13
+ ip: req.ip,
14
+ headers: req.headers,
15
+ body: req.body,
16
+ query: req.query
17
+ });
18
+
19
+ // Store original send and json methods
20
+ const originalSend = res.send;
21
+ const originalJson = res.json;
22
+
23
+ // Override send method to log response
24
+ res.send = function (body) {
25
+ console.log('Response:', {
26
+ timestamp: new Date().toISOString(),
27
+ statusCode: res.statusCode,
28
+ body: body
29
+ });
30
+ return originalSend.call(this, body);
31
+ };
32
+
33
+ // Override json method to log response
34
+ res.json = function (body) {
35
+ console.log('Response:', {
36
+ timestamp: new Date().toISOString(),
37
+ statusCode: res.statusCode,
38
+ body: body
39
+ });
40
+ return originalJson.call(this, body);
41
+ };
42
+ next();
43
+ };
44
+ module.exports = logger;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Response formatting middleware for Express applications
5
+ */
6
+
7
+ const responseHandler = (req, res, next) => {
8
+ // Add success method to response object
9
+ res.success = function (data = null, message = 'Success', statusCode = 200) {
10
+ return this.status(statusCode).json({
11
+ success: true,
12
+ message,
13
+ data
14
+ });
15
+ };
16
+
17
+ // Add error method to response object
18
+ res.error = function (message = 'Error', statusCode = 500, details = null) {
19
+ return this.status(statusCode).json({
20
+ success: false,
21
+ message,
22
+ details
23
+ });
24
+ };
25
+
26
+ // Store original json method
27
+ const originalJson = res.json;
28
+
29
+ // Override json method to ensure consistent format
30
+ res.json = function (data) {
31
+ // If response is already formatted, use original json
32
+ if (data && typeof data === 'object' && 'success' in data) {
33
+ return originalJson.call(this, data);
34
+ }
35
+
36
+ // Format the response
37
+ return originalJson.call(this, {
38
+ success: true,
39
+ data
40
+ });
41
+ };
42
+ next();
43
+ };
44
+ module.exports = responseHandler;
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Swagger configuration for Express applications
5
+ */
6
+
7
+ const swaggerJsdoc = require('swagger-jsdoc');
8
+ const createSwaggerSpec = (options = {}) => {
9
+ const defaultOptions = {
10
+ definition: {
11
+ openapi: '3.0.0',
12
+ info: {
13
+ title: options.title || 'API Documentation',
14
+ version: options.version || '1.0.0',
15
+ description: options.description || 'API documentation'
16
+ },
17
+ servers: [{
18
+ url: options.serverUrl || 'http://localhost:3000',
19
+ description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server'
20
+ }],
21
+ components: {
22
+ schemas: {
23
+ Error: {
24
+ type: 'object',
25
+ properties: {
26
+ success: {
27
+ type: 'boolean',
28
+ example: false
29
+ },
30
+ message: {
31
+ type: 'string',
32
+ example: 'Error message'
33
+ },
34
+ details: {
35
+ type: 'object',
36
+ example: null
37
+ }
38
+ }
39
+ },
40
+ Success: {
41
+ type: 'object',
42
+ properties: {
43
+ success: {
44
+ type: 'boolean',
45
+ example: true
46
+ },
47
+ message: {
48
+ type: 'string',
49
+ example: 'Operation successful'
50
+ },
51
+ data: {
52
+ type: 'object',
53
+ example: null
54
+ }
55
+ }
56
+ }
57
+ },
58
+ responses: {
59
+ UnauthorizedError: {
60
+ description: 'Access token is missing or invalid',
61
+ content: {
62
+ 'application/json': {
63
+ schema: {
64
+ $ref: '#/components/schemas/Error'
65
+ }
66
+ }
67
+ }
68
+ },
69
+ NotFoundError: {
70
+ description: 'The specified resource was not found',
71
+ content: {
72
+ 'application/json': {
73
+ schema: {
74
+ $ref: '#/components/schemas/Error'
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ },
82
+ apis: options.apis || ['./routes/*.js'] // Path to the API routes
83
+ };
84
+ const swaggerSpec = swaggerJsdoc(defaultOptions);
85
+
86
+ // Remove sensitive information in production
87
+ if (process.env.NODE_ENV === 'production') {
88
+ // Remove server URLs in production
89
+ swaggerSpec.servers = [];
90
+
91
+ // Remove any sensitive examples or descriptions
92
+ if (swaggerSpec.paths) {
93
+ Object.keys(swaggerSpec.paths).forEach(path => {
94
+ Object.keys(swaggerSpec.paths[path]).forEach(method => {
95
+ const operation = swaggerSpec.paths[path][method];
96
+ if (operation.responses) {
97
+ Object.keys(operation.responses).forEach(statusCode => {
98
+ const response = operation.responses[statusCode];
99
+ if (response.content) {
100
+ Object.keys(response.content).forEach(contentType => {
101
+ const content = response.content[contentType];
102
+ if (content.examples) {
103
+ delete content.examples;
104
+ }
105
+ });
106
+ }
107
+ });
108
+ }
109
+ });
110
+ });
111
+ }
112
+ }
113
+ return swaggerSpec;
114
+ };
115
+ module.exports = createSwaggerSpec;
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "powr-sdk-api",
3
+ "version": "1.0.0",
4
+ "description": "Shared API core library for PowrStack projects",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "scripts": {
12
+ "test": "jest --passWithNoTests",
13
+ "lint": "eslint .",
14
+ "build": "babel src -d dist",
15
+ "prepare": "npm run build",
16
+ "prepublishOnly": "npm run test"
17
+ },
18
+ "keywords": [
19
+ "api",
20
+ "express",
21
+ "middleware",
22
+ "error-handling",
23
+ "response-formatting",
24
+ "logging",
25
+ "swagger",
26
+ "documentation"
27
+ ],
28
+ "author": "PowrStack",
29
+ "license": "ISC",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/powrstack/powr-sdk-api.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/powrstack/powr-sdk-api/issues"
36
+ },
37
+ "homepage": "https://github.com/powrstack/powr-sdk-api#readme",
38
+ "dependencies": {
39
+ "express": "^4.18.2",
40
+ "swagger-jsdoc": "^6.2.8",
41
+ "swagger-ui-express": "^5.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@babel/cli": "^7.23.9",
45
+ "@babel/core": "^7.24.0",
46
+ "@babel/preset-env": "^7.24.0",
47
+ "@types/express": "^4.17.21",
48
+ "@types/swagger-jsdoc": "^6.0.4",
49
+ "@types/swagger-ui-express": "^4.1.6",
50
+ "eslint": "^8.57.0",
51
+ "jest": "^29.7.0",
52
+ "typescript": "^5.3.3"
53
+ },
54
+ "peerDependencies": {
55
+ "express": "^4.18.2"
56
+ },
57
+ "engines": {
58
+ "node": ">=14.0.0"
59
+ }
60
+ }