emessages 1.0.0 → 2.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,145 @@
1
+ # emessages
2
+
3
+ A simple and flexible error messaging utility for JavaScript and TypeScript applications. Works in both Node.js and the browser, supporting CJS and ESM modules.
4
+
5
+ ## Features
6
+
7
+ - **Flexible Configuration**: Define error messages with custom behaviors.
8
+ - **Global & Local Scope**: Set global messages for your entire application and override them with local messages in specific files.
9
+ - **Multiple Actions**: Show console messages (`log`, `warn`, `error`), halt execution, show browser toasts, return the message, and run callbacks.
10
+ - **TypeScript Ready**: Fully typed for a great developer experience.
11
+ - **Isomorphic**: Works on both frontend and backend.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install emessages
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### 1. Basic Usage
22
+
23
+ In your JavaScript or TypeScript file:
24
+
25
+ ```javascript
26
+ import { Emessage, showE } from "emessages";
27
+
28
+ // Define a local error message
29
+ Emessage({
30
+ GREETING_ERROR: "Cannot greet a user without a name.",
31
+ type: "war",
32
+ break: false, // Don't stop the code
33
+ });
34
+
35
+ function greet(name) {
36
+ if (!name) {
37
+ showE("GREETING_ERROR");
38
+ return;
39
+ }
40
+ console.log(`Hello, ${name}!`);
41
+ }
42
+
43
+ greet(); // outputs a warning
44
+ greet("World"); // outputs: "Hello, World!"
45
+ ```
46
+
47
+ ### 2. Global Messages (Optional)
48
+
49
+ To define messages that are accessible throughout your project, create a file (e.g., `globalMessages.ts`) and import it once in your application's entry point.
50
+
51
+ **`globalMessages.ts`**
52
+ ```javascript
53
+ import { Emessage } from "emessages";
54
+
55
+ // Use Emessage.global to define messages available everywhere
56
+ Emessage.global(
57
+ {
58
+ NAME_NOT_FOUND: "Name is required.",
59
+ type: "err",
60
+ break: false,
61
+ },
62
+ {
63
+ UNAUTHORIZED: "User is not authorized.",
64
+ type: "err",
65
+ tost: true,
66
+ }
67
+ );
68
+ ```
69
+
70
+ **`index.ts` (Your app's entry point)**
71
+ ```javascript
72
+ import "./globalMessages";
73
+ // ... rest of your app
74
+ ```
75
+
76
+ **Priority**: Messages defined with `Emessage` (local) will always take priority over messages defined with `Emessage.global`.
77
+
78
+ ### 3. Toast Notifications (Browser)
79
+
80
+ To use toast notifications, you must import the provided CSS file in your application.
81
+
82
+ ```javascript
83
+ // Example in a React/Vue/Svelte entry file
84
+ import "emessages/dist/emessages.css";
85
+ ```
86
+
87
+ Then, use the `tost` option:
88
+
89
+ ```javascript
90
+ Emessage({
91
+ STYLE_ERROR: "This will be a toast.",
92
+ type: "log", // It can be any type
93
+ tost: true, // Enable toast
94
+ break: false,
95
+ });
96
+
97
+ showE("STYLE_ERROR");
98
+ ```
99
+
100
+ You can also customize the toast:
101
+
102
+ ```javascript
103
+ showE({
104
+ CUSTOM_TOAST: "A custom toast!",
105
+ tost: {
106
+ message: "This message overrides the default.",
107
+ style: "text-yellow-400 text-base", // Custom CSS classes
108
+ position: "bottom-left",
109
+ },
110
+ break: false,
111
+ });
112
+ ```
113
+
114
+ ## API Reference
115
+
116
+ ### `Emessage(...configs)`
117
+
118
+ Defines one or more local error messages.
119
+
120
+ ### `Emessage.global(...configs)`
121
+
122
+ Defines one or more global error messages.
123
+
124
+ ### Config Object
125
+
126
+ Each config object passed to `Emessage` has one error name/message and a set of optional properties:
127
+
128
+ - `[errorName: string]: string`: The name of the error and its message.
129
+ - `type?`: `"log" | "war" | "err"`. The console method to use. **Default**: `"err"`.
130
+ - `break?`: `boolean`. If `true`, stops execution (throws in browser, `process.exit(1)` in Node.js). **Default**: `true`.
131
+ - `tost?`: `boolean | TostConfig`. If `true`, shows a toast. Can be an object for customization.
132
+ - `returnEM?`: `boolean`. If `true`, `showE` will return the error message as a string.
133
+ - `callBack?`: `() => void`. A function to execute.
134
+
135
+ **`TostConfig` Object**
136
+ - `message?`: `string`. A different message for the toast.
137
+ - `style?`: `string`. Custom CSS classes to apply.
138
+ - `position?`: `string`. e.g., `"top-right"`, `"bottom-left"`, `"center"`.
139
+
140
+ ### `showE(errorName | config)`
141
+
142
+ Triggers an error.
143
+
144
+ - `errorName: string`: The name of the pre-configured error to show. `showE` will look for a local definition first, then a global one.
145
+ - `config: object`: An inline config object for a one-off error message.
package/dist/index.cjs ADDED
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Emessage: () => Emessage,
24
+ showE: () => showE
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/store.ts
29
+ var individualMessageStore = /* @__PURE__ */ new Map();
30
+ var globalMessageStore = /* @__PURE__ */ new Map();
31
+
32
+ // src/utils.ts
33
+ function isBrowser() {
34
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
35
+ }
36
+ function showToast(message, tostConfig) {
37
+ if (!isBrowser()) {
38
+ return;
39
+ }
40
+ const toast = document.createElement("div");
41
+ const config = typeof tostConfig === "object" ? tostConfig : {};
42
+ toast.textContent = config.message || message;
43
+ toast.className = "emessage-toast";
44
+ if (config.style) {
45
+ toast.classList.add(...config.style.split(" "));
46
+ }
47
+ const position = config.position || "top-right";
48
+ toast.setAttribute("data-position", position);
49
+ document.body.appendChild(toast);
50
+ setTimeout(() => {
51
+ toast.classList.add("visible");
52
+ }, 10);
53
+ setTimeout(() => {
54
+ toast.classList.remove("visible");
55
+ toast.addEventListener("transitionend", () => {
56
+ if (toast.parentElement) {
57
+ toast.parentElement.removeChild(toast);
58
+ }
59
+ });
60
+ }, 3e3);
61
+ }
62
+
63
+ // src/index.ts
64
+ function parseConfig(config) {
65
+ const options = {};
66
+ let message = null;
67
+ let name = null;
68
+ const optionKeys = ["type", "break", "tost", "returnEM", "callBack"];
69
+ for (const key in config) {
70
+ if (Object.prototype.hasOwnProperty.call(config, key)) {
71
+ if (optionKeys.includes(key)) {
72
+ options[key] = config[key];
73
+ } else {
74
+ if (name !== null) {
75
+ console.warn(
76
+ `emessages: Found multiple potential error names in one config object. Using first one found: "${name}".`
77
+ );
78
+ continue;
79
+ }
80
+ name = key;
81
+ message = String(config[key]);
82
+ }
83
+ }
84
+ }
85
+ if (name === null || message === null) {
86
+ console.error(
87
+ "emessages: Invalid config object. Could not find error name and message.",
88
+ config
89
+ );
90
+ return null;
91
+ }
92
+ return { name, options: { ...options, message } };
93
+ }
94
+ function processEmessage(errorName, config) {
95
+ const message = config.message;
96
+ const type = config.type ?? "err";
97
+ switch (type) {
98
+ case "log":
99
+ console.log(message);
100
+ break;
101
+ case "war":
102
+ console.warn(message);
103
+ break;
104
+ case "err":
105
+ console.error(message);
106
+ break;
107
+ }
108
+ if (config.tost && isBrowser()) {
109
+ showToast(message, config.tost);
110
+ }
111
+ if (config.callBack) {
112
+ try {
113
+ config.callBack();
114
+ } catch (e) {
115
+ console.error(
116
+ `emessages: Error in callBack for "${errorName}":`,
117
+ e.message
118
+ );
119
+ }
120
+ }
121
+ if (config.returnEM) {
122
+ return message;
123
+ }
124
+ if (config.break ?? true) {
125
+ if (isBrowser()) {
126
+ throw new Error(message);
127
+ } else {
128
+ process.exit(1);
129
+ }
130
+ }
131
+ }
132
+ function Emessage(...configs) {
133
+ for (const config of configs) {
134
+ const parsed = parseConfig(config);
135
+ if (parsed) {
136
+ individualMessageStore.set(parsed.name, parsed.options);
137
+ }
138
+ }
139
+ }
140
+ Emessage.global = function(...configs) {
141
+ for (const config of configs) {
142
+ const parsed = parseConfig(config);
143
+ if (parsed) {
144
+ globalMessageStore.set(parsed.name, parsed.options);
145
+ }
146
+ }
147
+ };
148
+ function showE(error) {
149
+ let config = null;
150
+ let errorName = null;
151
+ if (typeof error === "string") {
152
+ errorName = error;
153
+ config = individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;
154
+ if (!config) {
155
+ console.error(`emessages: Error "${error}" not found.`);
156
+ return;
157
+ }
158
+ } else if (typeof error === "object" && error !== null) {
159
+ const parsed = parseConfig(error);
160
+ if (parsed) {
161
+ errorName = parsed.name;
162
+ config = parsed.options;
163
+ } else {
164
+ console.error("emessages: Invalid object passed to showE.");
165
+ return;
166
+ }
167
+ } else {
168
+ console.error("emessages: Invalid argument passed to showE.");
169
+ return;
170
+ }
171
+ if (config && errorName) {
172
+ return processEmessage(errorName, config);
173
+ }
174
+ }
175
+ // Annotate the CommonJS export names for ESM import in node:
176
+ 0 && (module.exports = {
177
+ Emessage,
178
+ showE
179
+ });
180
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/store.ts","../src/utils.ts"],"sourcesContent":["import { individualMessageStore, globalMessageStore } from \"./store\";\nimport type { EmessageOptions, StoredEmessage, TostConfig } from \"./types\";\nimport { isBrowser, showToast } from \"./utils\";\n\nfunction parseConfig(\n config: Record<string, any>\n): { name: string; options: StoredEmessage } | null {\n const options: EmessageOptions = {};\n let message: string | null = null;\n let name: string | null = null;\n const optionKeys = [\"type\", \"break\", \"tost\", \"returnEM\", \"callBack\"];\n\n for (const key in config) {\n if (Object.prototype.hasOwnProperty.call(config, key)) {\n if (optionKeys.includes(key)) {\n (options as any)[key] = config[key];\n } else {\n if (name !== null) {\n console.warn(\n `emessages: Found multiple potential error names in one config object. Using first one found: \"${name}\".`\n );\n continue;\n }\n name = key;\n message = String(config[key]);\n }\n }\n }\n\n if (name === null || message === null) {\n console.error(\n \"emessages: Invalid config object. Could not find error name and message.\",\n config\n );\n return null;\n }\n\n return { name, options: { ...options, message } };\n}\n\nfunction processEmessage(\n errorName: string,\n config: StoredEmessage\n): string | void {\n const message = config.message;\n const type = config.type ?? \"err\";\n\n // 1. Console log\n switch (type) {\n case \"log\":\n console.log(message);\n break;\n case \"war\":\n console.warn(message);\n break;\n case \"err\":\n console.error(message);\n break;\n }\n\n // 2. Toast notification\n if (config.tost && isBrowser()) {\n showToast(message, config.tost);\n }\n\n // 3. Callback\n if (config.callBack) {\n try {\n config.callBack();\n } catch (e: any) {\n console.error(\n `emessages: Error in callBack for \"${errorName}\":`,\n e.message\n );\n }\n }\n\n // 4. Return error message\n if (config.returnEM) {\n return message;\n }\n\n // 5. Break execution\n if (config.break ?? true) {\n if (isBrowser()) {\n throw new Error(message);\n } else {\n process.exit(1);\n }\n }\n}\n\nexport function Emessage(...configs: Record<string, any>[]) {\n for (const config of configs) {\n const parsed = parseConfig(config);\n if (parsed) {\n individualMessageStore.set(parsed.name, parsed.options);\n }\n }\n}\n\nEmessage.global = function (...configs: Record<string, any>[]) {\n for (const config of configs) {\n const parsed = parseConfig(config);\n if (parsed) {\n globalMessageStore.set(parsed.name, parsed.options);\n }\n }\n};\n\nexport function showE(error: string | Record<string, any>): string | void {\n let config: StoredEmessage | null = null;\n let errorName: string | null = null;\n\n if (typeof error === \"string\") {\n errorName = error;\n config =\n individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;\n if (!config) {\n console.error(`emessages: Error \"${error}\" not found.`);\n return;\n }\n } else if (typeof error === \"object\" && error !== null) {\n const parsed = parseConfig(error);\n if (parsed) {\n errorName = parsed.name;\n config = parsed.options;\n } else {\n console.error(\"emessages: Invalid object passed to showE.\");\n return;\n }\n } else {\n console.error(\"emessages: Invalid argument passed to showE.\");\n return;\n }\n\n if (config && errorName) {\n return processEmessage(errorName, config);\n }\n}\n","import type { StoredEmessage } from \"./types\";\n\nexport const individualMessageStore = new Map<string, StoredEmessage>();\nexport const globalMessageStore = new Map<string, StoredEmessage>();\n","import { TostConfig } from \"./types\";\n\nexport function isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n}\n\nexport function showToast(\n message: string,\n tostConfig: boolean | TostConfig\n): void {\n if (!isBrowser()) {\n return;\n }\n\n const toast = document.createElement(\"div\");\n\n const config: TostConfig = typeof tostConfig === \"object\" ? tostConfig : {};\n\n toast.textContent = config.message || message;\n\n // Base styles are applied via CSS, but some can be defaults.\n toast.className = \"emessage-toast\";\n if (config.style) {\n toast.classList.add(...config.style.split(\" \"));\n }\n\n // Positioning\n const position = config.position || \"top-right\";\n toast.setAttribute(\"data-position\", position);\n\n document.body.appendChild(toast);\n\n // Animate in\n setTimeout(() => {\n toast.classList.add(\"visible\");\n }, 10);\n\n // Animate out and remove\n setTimeout(() => {\n toast.classList.remove(\"visible\");\n toast.addEventListener(\"transitionend\", () => {\n if (toast.parentElement) {\n toast.parentElement.removeChild(toast);\n }\n });\n }, 3000);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,7 @@
1
+ declare function Emessage(...configs: Record<string, any>[]): void;
2
+ declare namespace Emessage {
3
+ var global: (...configs: Record<string, any>[]) => void;
4
+ }
5
+ declare function showE(error: string | Record<string, any>): string | void;
6
+
7
+ export { Emessage, showE };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,7 @@
1
- export type ErrorMap = Record<string, string>;
2
- export declare class ShowE extends Error {
3
- code: string;
4
- constructor(code: string);
1
+ declare function Emessage(...configs: Record<string, any>[]): void;
2
+ declare namespace Emessage {
3
+ var global: (...configs: Record<string, any>[]) => void;
5
4
  }
6
- declare global {
7
- interface Function {
8
- Emessage(map: ErrorMap): (...args: any[]) => Promise<any>;
9
- }
10
- }
11
- export {};
5
+ declare function showE(error: string | Record<string, any>): string | void;
6
+
7
+ export { Emessage, showE };
package/dist/index.mjs ADDED
@@ -0,0 +1,152 @@
1
+ // src/store.ts
2
+ var individualMessageStore = /* @__PURE__ */ new Map();
3
+ var globalMessageStore = /* @__PURE__ */ new Map();
4
+
5
+ // src/utils.ts
6
+ function isBrowser() {
7
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
8
+ }
9
+ function showToast(message, tostConfig) {
10
+ if (!isBrowser()) {
11
+ return;
12
+ }
13
+ const toast = document.createElement("div");
14
+ const config = typeof tostConfig === "object" ? tostConfig : {};
15
+ toast.textContent = config.message || message;
16
+ toast.className = "emessage-toast";
17
+ if (config.style) {
18
+ toast.classList.add(...config.style.split(" "));
19
+ }
20
+ const position = config.position || "top-right";
21
+ toast.setAttribute("data-position", position);
22
+ document.body.appendChild(toast);
23
+ setTimeout(() => {
24
+ toast.classList.add("visible");
25
+ }, 10);
26
+ setTimeout(() => {
27
+ toast.classList.remove("visible");
28
+ toast.addEventListener("transitionend", () => {
29
+ if (toast.parentElement) {
30
+ toast.parentElement.removeChild(toast);
31
+ }
32
+ });
33
+ }, 3e3);
34
+ }
35
+
36
+ // src/index.ts
37
+ function parseConfig(config) {
38
+ const options = {};
39
+ let message = null;
40
+ let name = null;
41
+ const optionKeys = ["type", "break", "tost", "returnEM", "callBack"];
42
+ for (const key in config) {
43
+ if (Object.prototype.hasOwnProperty.call(config, key)) {
44
+ if (optionKeys.includes(key)) {
45
+ options[key] = config[key];
46
+ } else {
47
+ if (name !== null) {
48
+ console.warn(
49
+ `emessages: Found multiple potential error names in one config object. Using first one found: "${name}".`
50
+ );
51
+ continue;
52
+ }
53
+ name = key;
54
+ message = String(config[key]);
55
+ }
56
+ }
57
+ }
58
+ if (name === null || message === null) {
59
+ console.error(
60
+ "emessages: Invalid config object. Could not find error name and message.",
61
+ config
62
+ );
63
+ return null;
64
+ }
65
+ return { name, options: { ...options, message } };
66
+ }
67
+ function processEmessage(errorName, config) {
68
+ const message = config.message;
69
+ const type = config.type ?? "err";
70
+ switch (type) {
71
+ case "log":
72
+ console.log(message);
73
+ break;
74
+ case "war":
75
+ console.warn(message);
76
+ break;
77
+ case "err":
78
+ console.error(message);
79
+ break;
80
+ }
81
+ if (config.tost && isBrowser()) {
82
+ showToast(message, config.tost);
83
+ }
84
+ if (config.callBack) {
85
+ try {
86
+ config.callBack();
87
+ } catch (e) {
88
+ console.error(
89
+ `emessages: Error in callBack for "${errorName}":`,
90
+ e.message
91
+ );
92
+ }
93
+ }
94
+ if (config.returnEM) {
95
+ return message;
96
+ }
97
+ if (config.break ?? true) {
98
+ if (isBrowser()) {
99
+ throw new Error(message);
100
+ } else {
101
+ process.exit(1);
102
+ }
103
+ }
104
+ }
105
+ function Emessage(...configs) {
106
+ for (const config of configs) {
107
+ const parsed = parseConfig(config);
108
+ if (parsed) {
109
+ individualMessageStore.set(parsed.name, parsed.options);
110
+ }
111
+ }
112
+ }
113
+ Emessage.global = function(...configs) {
114
+ for (const config of configs) {
115
+ const parsed = parseConfig(config);
116
+ if (parsed) {
117
+ globalMessageStore.set(parsed.name, parsed.options);
118
+ }
119
+ }
120
+ };
121
+ function showE(error) {
122
+ let config = null;
123
+ let errorName = null;
124
+ if (typeof error === "string") {
125
+ errorName = error;
126
+ config = individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;
127
+ if (!config) {
128
+ console.error(`emessages: Error "${error}" not found.`);
129
+ return;
130
+ }
131
+ } else if (typeof error === "object" && error !== null) {
132
+ const parsed = parseConfig(error);
133
+ if (parsed) {
134
+ errorName = parsed.name;
135
+ config = parsed.options;
136
+ } else {
137
+ console.error("emessages: Invalid object passed to showE.");
138
+ return;
139
+ }
140
+ } else {
141
+ console.error("emessages: Invalid argument passed to showE.");
142
+ return;
143
+ }
144
+ if (config && errorName) {
145
+ return processEmessage(errorName, config);
146
+ }
147
+ }
148
+ export {
149
+ Emessage,
150
+ showE
151
+ };
152
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { StoredEmessage } from \"./types\";\n\nexport const individualMessageStore = new Map<string, StoredEmessage>();\nexport const globalMessageStore = new Map<string, StoredEmessage>();\n","import { TostConfig } from \"./types\";\n\nexport function isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n}\n\nexport function showToast(\n message: string,\n tostConfig: boolean | TostConfig\n): void {\n if (!isBrowser()) {\n return;\n }\n\n const toast = document.createElement(\"div\");\n\n const config: TostConfig = typeof tostConfig === \"object\" ? tostConfig : {};\n\n toast.textContent = config.message || message;\n\n // Base styles are applied via CSS, but some can be defaults.\n toast.className = \"emessage-toast\";\n if (config.style) {\n toast.classList.add(...config.style.split(\" \"));\n }\n\n // Positioning\n const position = config.position || \"top-right\";\n toast.setAttribute(\"data-position\", position);\n\n document.body.appendChild(toast);\n\n // Animate in\n setTimeout(() => {\n toast.classList.add(\"visible\");\n }, 10);\n\n // Animate out and remove\n setTimeout(() => {\n toast.classList.remove(\"visible\");\n toast.addEventListener(\"transitionend\", () => {\n if (toast.parentElement) {\n toast.parentElement.removeChild(toast);\n }\n });\n }, 3000);\n}\n","import { individualMessageStore, globalMessageStore } from \"./store\";\nimport type { EmessageOptions, StoredEmessage, TostConfig } from \"./types\";\nimport { isBrowser, showToast } from \"./utils\";\n\nfunction parseConfig(\n config: Record<string, any>\n): { name: string; options: StoredEmessage } | null {\n const options: EmessageOptions = {};\n let message: string | null = null;\n let name: string | null = null;\n const optionKeys = [\"type\", \"break\", \"tost\", \"returnEM\", \"callBack\"];\n\n for (const key in config) {\n if (Object.prototype.hasOwnProperty.call(config, key)) {\n if (optionKeys.includes(key)) {\n (options as any)[key] = config[key];\n } else {\n if (name !== null) {\n console.warn(\n `emessages: Found multiple potential error names in one config object. Using first one found: \"${name}\".`\n );\n continue;\n }\n name = key;\n message = String(config[key]);\n }\n }\n }\n\n if (name === null || message === null) {\n console.error(\n \"emessages: Invalid config object. Could not find error name and message.\",\n config\n );\n return null;\n }\n\n return { name, options: { ...options, message } };\n}\n\nfunction processEmessage(\n errorName: string,\n config: StoredEmessage\n): string | void {\n const message = config.message;\n const type = config.type ?? \"err\";\n\n // 1. Console log\n switch (type) {\n case \"log\":\n console.log(message);\n break;\n case \"war\":\n console.warn(message);\n break;\n case \"err\":\n console.error(message);\n break;\n }\n\n // 2. Toast notification\n if (config.tost && isBrowser()) {\n showToast(message, config.tost);\n }\n\n // 3. Callback\n if (config.callBack) {\n try {\n config.callBack();\n } catch (e: any) {\n console.error(\n `emessages: Error in callBack for \"${errorName}\":`,\n e.message\n );\n }\n }\n\n // 4. Return error message\n if (config.returnEM) {\n return message;\n }\n\n // 5. Break execution\n if (config.break ?? true) {\n if (isBrowser()) {\n throw new Error(message);\n } else {\n process.exit(1);\n }\n }\n}\n\nexport function Emessage(...configs: Record<string, any>[]) {\n for (const config of configs) {\n const parsed = parseConfig(config);\n if (parsed) {\n individualMessageStore.set(parsed.name, parsed.options);\n }\n }\n}\n\nEmessage.global = function (...configs: Record<string, any>[]) {\n for (const config of configs) {\n const parsed = parseConfig(config);\n if (parsed) {\n globalMessageStore.set(parsed.name, parsed.options);\n }\n }\n};\n\nexport function showE(error: string | Record<string, any>): string | void {\n let config: StoredEmessage | null = null;\n let errorName: string | null = null;\n\n if (typeof error === \"string\") {\n errorName = error;\n config =\n individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;\n if (!config) {\n console.error(`emessages: Error \"${error}\" not found.`);\n return;\n }\n } else if (typeof error === \"object\" && error !== null) {\n const parsed = parseConfig(error);\n if (parsed) {\n errorName = parsed.name;\n config = parsed.options;\n } else {\n console.error(\"emessages: Invalid object passed to showE.\");\n return;\n }\n } else {\n console.error(\"emessages: Invalid argument passed to showE.\");\n return;\n }\n\n if (config && errorName) {\n return processEmessage(errorName, config);\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,25 +1,36 @@
1
- {
2
- "name": "emessages",
3
- "version": "1.0.0",
4
- "description": "Function prototype based error handler with code-to-message mapping",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
-
9
- "exports": {
10
- ".": {
11
- "import": "./dist/index.js",
12
- "types": "./dist/index.d.ts"
13
- }
14
- },
15
-
16
- "sideEffects": true,
17
-
18
- "scripts": {
19
- "build": "tsc"
20
- },
21
-
22
- "devDependencies": {
23
- "typescript": "^5.9.3"
24
- }
25
- }
1
+ {
2
+ "name": "emessages",
3
+ "version": "2.0.0",
4
+ "description": "A flexible error handling library for JS/TS. Define custom errors with console, toast, and callbacks, supporting global/local scopes and all environments.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.cjs"
17
+ },
18
+ "./dist/emessages.css": "./dist/emessages.css"
19
+ },
20
+ "keywords": [
21
+ "error",
22
+ "message",
23
+ "logging",
24
+ "toast",
25
+ "notification"
26
+ ],
27
+ "sideEffects": true,
28
+ "scripts": {
29
+ "build": "tsup"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^20.11.24",
33
+ "tsup": "^8.0.2",
34
+ "typescript": "^5.3.3"
35
+ }
36
+ }
package/dist/index.js DELETED
@@ -1,23 +0,0 @@
1
- export class ShowE extends Error {
2
- constructor(code) {
3
- super(code);
4
- this.code = code;
5
- }
6
- }
7
- const wrapWithHandler = (func, messages) => {
8
- return async (...args) => {
9
- var _a, _b;
10
- try {
11
- return await func(...args);
12
- }
13
- catch (error) {
14
- const errorCode = (_a = error === null || error === void 0 ? void 0 : error.code) !== null && _a !== void 0 ? _a : "UNKNOWN_ERROR";
15
- const message = (_b = messages[errorCode]) !== null && _b !== void 0 ? _b : "Unexpected error occurred";
16
- console.error(`[${func.name || "anonymous"}] ${message}`);
17
- }
18
- };
19
- };
20
- // 🔥 Prototype extension — runs when module is imported
21
- Function.prototype.Emessage = function (map) {
22
- return wrapWithHandler(this, map);
23
- };
package/src/index.ts DELETED
@@ -1,37 +0,0 @@
1
- export type ErrorMap = Record<string, string>;
2
-
3
- export class ShowE extends Error {
4
- code: string;
5
-
6
- constructor(code: string) {
7
- super(code);
8
- this.code = code;
9
- }
10
- }
11
-
12
- const wrapWithHandler = (func: Function, messages: ErrorMap) => {
13
- return async (...args: any[]) => {
14
- try {
15
- return await func(...args);
16
- } catch (error: any) {
17
- const errorCode = error?.code ?? "UNKNOWN_ERROR";
18
- const message = messages[errorCode] ?? "Unexpected error occurred";
19
- console.error(`[${func.name || "anonymous"}] ${message}`);
20
- }
21
- };
22
- };
23
-
24
- // 🌍 Global augmentation
25
- declare global {
26
- interface Function {
27
- Emessage(map: ErrorMap): (...args: any[]) => Promise<any>;
28
- }
29
- }
30
-
31
- // 🔥 Prototype extension — runs when module is imported
32
- Function.prototype.Emessage = function (map: ErrorMap) {
33
- return wrapWithHandler(this, map);
34
- };
35
-
36
- // Required for global augmentation
37
- export {};
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2019",
4
- "module": "ESNext",
5
- "declaration": true,
6
- "outDir": "dist",
7
- "strict": true,
8
- "esModuleInterop": true
9
- },
10
- "include": ["src"]
11
- }