@periodic/obsidian 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/dist/index.mjs ADDED
@@ -0,0 +1,391 @@
1
+ // src/core/status-codes.ts
2
+ var HttpStatusCode = {
3
+ // 1xx Informational
4
+ CONTINUE: 100,
5
+ SWITCHING_PROTOCOLS: 101,
6
+ PROCESSING: 102,
7
+ EARLY_HINTS: 103,
8
+ // 2xx Success
9
+ OK: 200,
10
+ CREATED: 201,
11
+ ACCEPTED: 202,
12
+ NON_AUTHORITATIVE_INFORMATION: 203,
13
+ NO_CONTENT: 204,
14
+ RESET_CONTENT: 205,
15
+ PARTIAL_CONTENT: 206,
16
+ MULTI_STATUS: 207,
17
+ ALREADY_REPORTED: 208,
18
+ IM_USED: 226,
19
+ // 3xx Redirection
20
+ MULTIPLE_CHOICES: 300,
21
+ MOVED_PERMANENTLY: 301,
22
+ FOUND: 302,
23
+ SEE_OTHER: 303,
24
+ NOT_MODIFIED: 304,
25
+ USE_PROXY: 305,
26
+ TEMPORARY_REDIRECT: 307,
27
+ PERMANENT_REDIRECT: 308,
28
+ // 4xx Client Errors
29
+ BAD_REQUEST: 400,
30
+ UNAUTHORIZED: 401,
31
+ PAYMENT_REQUIRED: 402,
32
+ FORBIDDEN: 403,
33
+ NOT_FOUND: 404,
34
+ METHOD_NOT_ALLOWED: 405,
35
+ NOT_ACCEPTABLE: 406,
36
+ PROXY_AUTHENTICATION_REQUIRED: 407,
37
+ REQUEST_TIMEOUT: 408,
38
+ CONFLICT: 409,
39
+ GONE: 410,
40
+ LENGTH_REQUIRED: 411,
41
+ PRECONDITION_FAILED: 412,
42
+ PAYLOAD_TOO_LARGE: 413,
43
+ URI_TOO_LONG: 414,
44
+ UNSUPPORTED_MEDIA_TYPE: 415,
45
+ RANGE_NOT_SATISFIABLE: 416,
46
+ EXPECTATION_FAILED: 417,
47
+ IM_A_TEAPOT: 418,
48
+ MISDIRECTED_REQUEST: 421,
49
+ UNPROCESSABLE_ENTITY: 422,
50
+ LOCKED: 423,
51
+ FAILED_DEPENDENCY: 424,
52
+ TOO_EARLY: 425,
53
+ UPGRADE_REQUIRED: 426,
54
+ PRECONDITION_REQUIRED: 428,
55
+ TOO_MANY_REQUESTS: 429,
56
+ REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
57
+ UNAVAILABLE_FOR_LEGAL_REASONS: 451,
58
+ // 5xx Server Errors
59
+ INTERNAL_SERVER_ERROR: 500,
60
+ NOT_IMPLEMENTED: 501,
61
+ BAD_GATEWAY: 502,
62
+ SERVICE_UNAVAILABLE: 503,
63
+ GATEWAY_TIMEOUT: 504,
64
+ HTTP_VERSION_NOT_SUPPORTED: 505,
65
+ VARIANT_ALSO_NEGOTIATES: 506,
66
+ INSUFFICIENT_STORAGE: 507,
67
+ LOOP_DETECTED: 508,
68
+ NOT_EXTENDED: 510,
69
+ NETWORK_AUTHENTICATION_REQUIRED: 511
70
+ };
71
+ var HttpStatusMessage = {
72
+ // 1xx Informational
73
+ 100: "Continue",
74
+ 101: "Switching Protocols",
75
+ 102: "Processing",
76
+ 103: "Early Hints",
77
+ // 2xx Success
78
+ 200: "OK",
79
+ 201: "Created",
80
+ 202: "Accepted",
81
+ 203: "Non-Authoritative Information",
82
+ 204: "No Content",
83
+ 205: "Reset Content",
84
+ 206: "Partial Content",
85
+ 207: "Multi-Status",
86
+ 208: "Already Reported",
87
+ 226: "IM Used",
88
+ // 3xx Redirection
89
+ 300: "Multiple Choices",
90
+ 301: "Moved Permanently",
91
+ 302: "Found",
92
+ 303: "See Other",
93
+ 304: "Not Modified",
94
+ 305: "Use Proxy",
95
+ 307: "Temporary Redirect",
96
+ 308: "Permanent Redirect",
97
+ // 4xx Client Errors
98
+ 400: "Bad Request",
99
+ 401: "Unauthorized",
100
+ 402: "Payment Required",
101
+ 403: "Forbidden",
102
+ 404: "Not Found",
103
+ 405: "Method Not Allowed",
104
+ 406: "Not Acceptable",
105
+ 407: "Proxy Authentication Required",
106
+ 408: "Request Timeout",
107
+ 409: "Conflict",
108
+ 410: "Gone",
109
+ 411: "Length Required",
110
+ 412: "Precondition Failed",
111
+ 413: "Payload Too Large",
112
+ 414: "URI Too Long",
113
+ 415: "Unsupported Media Type",
114
+ 416: "Range Not Satisfiable",
115
+ 417: "Expectation Failed",
116
+ 418: "I'm a Teapot",
117
+ 421: "Misdirected Request",
118
+ 422: "Unprocessable Entity",
119
+ 423: "Locked",
120
+ 424: "Failed Dependency",
121
+ 425: "Too Early",
122
+ 426: "Upgrade Required",
123
+ 428: "Precondition Required",
124
+ 429: "Too Many Requests",
125
+ 431: "Request Header Fields Too Large",
126
+ 451: "Unavailable For Legal Reasons",
127
+ // 5xx Server Errors
128
+ 500: "Internal Server Error",
129
+ 501: "Not Implemented",
130
+ 502: "Bad Gateway",
131
+ 503: "Service Unavailable",
132
+ 504: "Gateway Timeout",
133
+ 505: "HTTP Version Not Supported",
134
+ 506: "Variant Also Negotiates",
135
+ 507: "Insufficient Storage",
136
+ 508: "Loop Detected",
137
+ 510: "Not Extended",
138
+ 511: "Network Authentication Required"
139
+ };
140
+
141
+ // src/core/http-error.ts
142
+ var HttpError = class _HttpError extends Error {
143
+ /**
144
+ * Creates a new HTTP error
145
+ *
146
+ * @param status - HTTP status code
147
+ * @param message - Human-readable error message
148
+ * @param options - Optional error metadata
149
+ */
150
+ constructor(status, message, options) {
151
+ super(message);
152
+ Object.setPrototypeOf(this, _HttpError.prototype);
153
+ this.name = "HttpError";
154
+ this.status = status;
155
+ this.code = options?.code;
156
+ this.details = options?.details;
157
+ if (Error.captureStackTrace) {
158
+ Error.captureStackTrace(this, this.constructor);
159
+ }
160
+ }
161
+ /**
162
+ * Serializes the error to a plain JSON object
163
+ *
164
+ * @returns JSON representation without stack trace
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * const error = new HttpError(404, 'Not found');
169
+ * console.log(error.toJSON());
170
+ * // { status: 404, message: 'Not found' }
171
+ * ```
172
+ */
173
+ toJSON() {
174
+ const json = {
175
+ status: this.status,
176
+ message: this.message
177
+ };
178
+ if (this.code !== void 0) {
179
+ json.code = this.code;
180
+ }
181
+ if (this.details !== void 0) {
182
+ json.details = this.details;
183
+ }
184
+ return json;
185
+ }
186
+ /**
187
+ * Returns the default message for a given HTTP status code
188
+ *
189
+ * @param status - HTTP status code
190
+ * @returns Default status message or 'Unknown Error'
191
+ */
192
+ static getDefaultMessage(status) {
193
+ return HttpStatusMessage[status] || "Unknown Error";
194
+ }
195
+ };
196
+
197
+ // src/adapters/express.ts
198
+ function errorHandler(options = {}) {
199
+ const { includeStack = process.env.NODE_ENV !== "production", logger, transform } = options;
200
+ return (err, req, res, _next) => {
201
+ if (logger) {
202
+ logger(err, req);
203
+ }
204
+ if (err instanceof HttpError) {
205
+ const response = transform ? transform(err) : err.toJSON();
206
+ res.status(err.status).json(response);
207
+ return;
208
+ }
209
+ if (!includeStack) {
210
+ res.status(500).json({
211
+ status: 500,
212
+ message: "Internal Server Error"
213
+ });
214
+ return;
215
+ }
216
+ res.status(500).json({
217
+ status: 500,
218
+ message: err.message,
219
+ stack: err.stack
220
+ });
221
+ };
222
+ }
223
+ function simpleErrorHandler() {
224
+ return (err, _req, res, next) => {
225
+ if (err instanceof HttpError) {
226
+ res.status(err.status).json(err.toJSON());
227
+ return;
228
+ }
229
+ next(err);
230
+ };
231
+ }
232
+
233
+ // src/core/factories.ts
234
+ function createFactory(status) {
235
+ return (message, options) => {
236
+ const errorMessage = message || HttpError.getDefaultMessage(status);
237
+ return new HttpError(status, errorMessage, options);
238
+ };
239
+ }
240
+ var continueError = createFactory(HttpStatusCode.CONTINUE);
241
+ var switchingProtocols = createFactory(HttpStatusCode.SWITCHING_PROTOCOLS);
242
+ var processing = createFactory(HttpStatusCode.PROCESSING);
243
+ var earlyHints = createFactory(HttpStatusCode.EARLY_HINTS);
244
+ var ok = createFactory(HttpStatusCode.OK);
245
+ var created = createFactory(HttpStatusCode.CREATED);
246
+ var accepted = createFactory(HttpStatusCode.ACCEPTED);
247
+ var nonAuthoritativeInformation = createFactory(
248
+ HttpStatusCode.NON_AUTHORITATIVE_INFORMATION
249
+ );
250
+ var noContent = createFactory(HttpStatusCode.NO_CONTENT);
251
+ var resetContent = createFactory(HttpStatusCode.RESET_CONTENT);
252
+ var partialContent = createFactory(HttpStatusCode.PARTIAL_CONTENT);
253
+ var multiStatus = createFactory(HttpStatusCode.MULTI_STATUS);
254
+ var alreadyReported = createFactory(HttpStatusCode.ALREADY_REPORTED);
255
+ var imUsed = createFactory(HttpStatusCode.IM_USED);
256
+ var multipleChoices = createFactory(HttpStatusCode.MULTIPLE_CHOICES);
257
+ var movedPermanently = createFactory(HttpStatusCode.MOVED_PERMANENTLY);
258
+ var found = createFactory(HttpStatusCode.FOUND);
259
+ var seeOther = createFactory(HttpStatusCode.SEE_OTHER);
260
+ var notModified = createFactory(HttpStatusCode.NOT_MODIFIED);
261
+ var useProxy = createFactory(HttpStatusCode.USE_PROXY);
262
+ var temporaryRedirect = createFactory(HttpStatusCode.TEMPORARY_REDIRECT);
263
+ var permanentRedirect = createFactory(HttpStatusCode.PERMANENT_REDIRECT);
264
+ var badRequest = createFactory(HttpStatusCode.BAD_REQUEST);
265
+ var unauthorized = createFactory(HttpStatusCode.UNAUTHORIZED);
266
+ var paymentRequired = createFactory(HttpStatusCode.PAYMENT_REQUIRED);
267
+ var forbidden = createFactory(HttpStatusCode.FORBIDDEN);
268
+ var notFound = createFactory(HttpStatusCode.NOT_FOUND);
269
+ var methodNotAllowed = createFactory(HttpStatusCode.METHOD_NOT_ALLOWED);
270
+ var notAcceptable = createFactory(HttpStatusCode.NOT_ACCEPTABLE);
271
+ var proxyAuthenticationRequired = createFactory(
272
+ HttpStatusCode.PROXY_AUTHENTICATION_REQUIRED
273
+ );
274
+ var requestTimeout = createFactory(HttpStatusCode.REQUEST_TIMEOUT);
275
+ var conflict = createFactory(HttpStatusCode.CONFLICT);
276
+ var gone = createFactory(HttpStatusCode.GONE);
277
+ var lengthRequired = createFactory(HttpStatusCode.LENGTH_REQUIRED);
278
+ var preconditionFailed = createFactory(HttpStatusCode.PRECONDITION_FAILED);
279
+ var payloadTooLarge = createFactory(HttpStatusCode.PAYLOAD_TOO_LARGE);
280
+ var uriTooLong = createFactory(HttpStatusCode.URI_TOO_LONG);
281
+ var unsupportedMediaType = createFactory(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE);
282
+ var rangeNotSatisfiable = createFactory(HttpStatusCode.RANGE_NOT_SATISFIABLE);
283
+ var expectationFailed = createFactory(HttpStatusCode.EXPECTATION_FAILED);
284
+ var imATeapot = createFactory(HttpStatusCode.IM_A_TEAPOT);
285
+ var misdirectedRequest = createFactory(HttpStatusCode.MISDIRECTED_REQUEST);
286
+ var unprocessableEntity = createFactory(HttpStatusCode.UNPROCESSABLE_ENTITY);
287
+ var locked = createFactory(HttpStatusCode.LOCKED);
288
+ var failedDependency = createFactory(HttpStatusCode.FAILED_DEPENDENCY);
289
+ var tooEarly = createFactory(HttpStatusCode.TOO_EARLY);
290
+ var upgradeRequired = createFactory(HttpStatusCode.UPGRADE_REQUIRED);
291
+ var preconditionRequired = createFactory(HttpStatusCode.PRECONDITION_REQUIRED);
292
+ var tooManyRequests = createFactory(HttpStatusCode.TOO_MANY_REQUESTS);
293
+ var requestHeaderFieldsTooLarge = createFactory(
294
+ HttpStatusCode.REQUEST_HEADER_FIELDS_TOO_LARGE
295
+ );
296
+ var unavailableForLegalReasons = createFactory(
297
+ HttpStatusCode.UNAVAILABLE_FOR_LEGAL_REASONS
298
+ );
299
+ var internalServerError = createFactory(HttpStatusCode.INTERNAL_SERVER_ERROR);
300
+ var notImplemented = createFactory(HttpStatusCode.NOT_IMPLEMENTED);
301
+ var badGateway = createFactory(HttpStatusCode.BAD_GATEWAY);
302
+ var serviceUnavailable = createFactory(HttpStatusCode.SERVICE_UNAVAILABLE);
303
+ var gatewayTimeout = createFactory(HttpStatusCode.GATEWAY_TIMEOUT);
304
+ var httpVersionNotSupported = createFactory(HttpStatusCode.HTTP_VERSION_NOT_SUPPORTED);
305
+ var variantAlsoNegotiates = createFactory(HttpStatusCode.VARIANT_ALSO_NEGOTIATES);
306
+ var insufficientStorage = createFactory(HttpStatusCode.INSUFFICIENT_STORAGE);
307
+ var loopDetected = createFactory(HttpStatusCode.LOOP_DETECTED);
308
+ var notExtended = createFactory(HttpStatusCode.NOT_EXTENDED);
309
+ var networkAuthenticationRequired = createFactory(
310
+ HttpStatusCode.NETWORK_AUTHENTICATION_REQUIRED
311
+ );
312
+
313
+ // src/index.ts
314
+ var obsidian = {
315
+ // 1xx Informational
316
+ continue: continueError,
317
+ switchingProtocols,
318
+ processing,
319
+ earlyHints,
320
+ // 2xx Success
321
+ ok,
322
+ created,
323
+ accepted,
324
+ nonAuthoritativeInformation,
325
+ noContent,
326
+ resetContent,
327
+ partialContent,
328
+ multiStatus,
329
+ alreadyReported,
330
+ imUsed,
331
+ // 3xx Redirection
332
+ multipleChoices,
333
+ movedPermanently,
334
+ found,
335
+ seeOther,
336
+ notModified,
337
+ useProxy,
338
+ temporaryRedirect,
339
+ permanentRedirect,
340
+ // 4xx Client Errors
341
+ badRequest,
342
+ unauthorized,
343
+ paymentRequired,
344
+ forbidden,
345
+ notFound,
346
+ methodNotAllowed,
347
+ notAcceptable,
348
+ proxyAuthenticationRequired,
349
+ requestTimeout,
350
+ conflict,
351
+ gone,
352
+ lengthRequired,
353
+ preconditionFailed,
354
+ payloadTooLarge,
355
+ uriTooLong,
356
+ unsupportedMediaType,
357
+ rangeNotSatisfiable,
358
+ expectationFailed,
359
+ imATeapot,
360
+ misdirectedRequest,
361
+ unprocessableEntity,
362
+ locked,
363
+ failedDependency,
364
+ tooEarly,
365
+ upgradeRequired,
366
+ preconditionRequired,
367
+ tooManyRequests,
368
+ requestHeaderFieldsTooLarge,
369
+ unavailableForLegalReasons,
370
+ // 5xx Server Errors
371
+ internalServerError,
372
+ badGateway,
373
+ serviceUnavailable,
374
+ gatewayTimeout,
375
+ notImplemented,
376
+ httpVersionNotSupported,
377
+ variantAlsoNegotiates,
378
+ insufficientStorage,
379
+ loopDetected,
380
+ notExtended,
381
+ networkAuthenticationRequired
382
+ };
383
+ export {
384
+ HttpError,
385
+ HttpStatusCode,
386
+ HttpStatusMessage,
387
+ errorHandler,
388
+ obsidian,
389
+ simpleErrorHandler,
390
+ obsidian as titanium
391
+ };
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@periodic/obsidian",
3
+ "version": "1.0.0",
4
+ "description": "A tiny, framework-agnostic, TypeScript-first HTTP error library with factory helpers for every standard HTTP status code",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
22
+ "test": "jest",
23
+ "test:watch": "jest --watch",
24
+ "test:coverage": "jest --coverage",
25
+ "typecheck": "tsc --noEmit",
26
+ "lint": "eslint src tests --ext .ts",
27
+ "lint:fix": "eslint src tests --ext .ts --fix",
28
+ "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"examples/**/*.ts\"",
29
+ "format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"examples/**/*.ts\"",
30
+ "prepublishOnly": "npm run build"
31
+ },
32
+ "keywords": [
33
+ "http",
34
+ "errors",
35
+ "express",
36
+ "fastify",
37
+ "nestjs",
38
+ "typescript",
39
+ "status-codes",
40
+ "error-handling",
41
+ "backend",
42
+ "rest-api",
43
+ "obsidian",
44
+ "periodic"
45
+ ],
46
+ "author": "Uday Thakur <udaythakurwork@gmail.com>",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/udaythakur7469/periodic-obsidian.git"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/udaythakur7469/periodic-obsidian/issues"
54
+ },
55
+ "homepage": "https://github.com/udaythakur7469/periodic-obsidian#readme",
56
+ "devDependencies": {
57
+ "@types/express": "^4.17.21",
58
+ "@types/jest": "^29.5.11",
59
+ "@types/node": "^20.11.0",
60
+ "@typescript-eslint/eslint-plugin": "^6.18.1",
61
+ "@typescript-eslint/parser": "^6.18.1",
62
+ "eslint": "^8.56.0",
63
+ "eslint-config-prettier": "^9.1.0",
64
+ "eslint-plugin-prettier": "^5.1.3",
65
+ "jest": "^29.7.0",
66
+ "prettier": "^3.2.4",
67
+ "ts-jest": "^29.1.1",
68
+ "tsup": "^8.0.1",
69
+ "typescript": "^5.3.3"
70
+ },
71
+ "peerDependencies": {
72
+ "express": "^4.0.0 || ^5.0.0"
73
+ },
74
+ "peerDependenciesMeta": {
75
+ "express": {
76
+ "optional": true
77
+ }
78
+ },
79
+ "engines": {
80
+ "node": ">=16.0.0"
81
+ }
82
+ }