emessages 2.2.0 → 2.2.4

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/cli.cjs ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli.ts
27
+ var fs = __toESM(require("fs"), 1);
28
+ var path = __toESM(require("path"), 1);
29
+ var readline = __toESM(require("readline"), 1);
30
+ var fileName = "EmessageGlobal";
31
+ var jsContent = `export const Emessage_global = [
32
+ {
33
+ GLOBAL_ERROR_MESSAGE: "Global error message.",
34
+ type:"war",
35
+ break:false,
36
+ toast: true
37
+ },
38
+ // {
39
+ // Add your custom global messages here.
40
+ // }
41
+ ];
42
+ `;
43
+ var tsContent = `export const Emessage_global = [
44
+ {
45
+ GLOBAL_ERROR_MESSAGE: "Global error message.",
46
+ type:"war",
47
+ break:false,
48
+ toast: true
49
+ },
50
+ // {
51
+ // Add your custom global messages here.
52
+ // }
53
+ ];
54
+ `;
55
+ function findProjectRoot(startDir) {
56
+ let currentDir = startDir;
57
+ while (currentDir !== path.parse(currentDir).root) {
58
+ if (fs.existsSync(path.join(currentDir, "package.json"))) {
59
+ return currentDir;
60
+ }
61
+ currentDir = path.dirname(currentDir);
62
+ }
63
+ return null;
64
+ }
65
+ function generateGlobalEmessageFile() {
66
+ const rl = readline.createInterface({
67
+ input: process.stdin,
68
+ output: process.stdout
69
+ });
70
+ rl.question("You want to create EmessageGlobal file: (y) ", (answer) => {
71
+ if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes" || answer === "") {
72
+ const cwd = process.cwd();
73
+ const projectRoot = findProjectRoot(cwd);
74
+ if (!projectRoot) {
75
+ console.error("Error: Could not find project root (package.json not found).");
76
+ process.exit(1);
77
+ }
78
+ const tsconfigPath = path.join(projectRoot, "tsconfig.json");
79
+ const isTypeScriptProject = fs.existsSync(tsconfigPath);
80
+ const fileExtension = isTypeScriptProject ? "ts" : "js";
81
+ const content = isTypeScriptProject ? tsContent : jsContent;
82
+ const outputFileName = `${fileName}.${fileExtension}`;
83
+ const outputPath = path.join(projectRoot, outputFileName);
84
+ if (fs.existsSync(outputPath)) {
85
+ console.warn(`Warning: ${outputFileName} already exists. Skipping file creation.`);
86
+ process.exit(0);
87
+ }
88
+ try {
89
+ fs.writeFileSync(outputPath, content, "utf8");
90
+ console.log(`Successfully created ${outputFileName} in your project root.`);
91
+ console.log("You can now configure global messages by editing this file.");
92
+ } catch (error) {
93
+ console.error(`Error creating ${outputFileName}:`, error.message);
94
+ process.exit(1);
95
+ }
96
+ }
97
+ rl.close();
98
+ });
99
+ }
100
+ generateGlobalEmessageFile();
101
+ //# sourceMappingURL=cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as readline from 'readline';\n\nconst fileName = 'EmessageGlobal';\nconst jsContent = `export const Emessage_global = [\n {\n GLOBAL_ERROR_MESSAGE: \"Global error message.\",\n type:\"war\",\n break:false,\n toast: true\n },\n // {\n // Add your custom global messages here.\n // }\n];\n`;\n\nconst tsContent = `export const Emessage_global = [\n {\n GLOBAL_ERROR_MESSAGE: \"Global error message.\",\n type:\"war\",\n break:false,\n toast: true\n },\n // {\n // Add your custom global messages here.\n // }\n];\n`;\n\nfunction findProjectRoot(startDir: string): string | null {\n let currentDir = startDir;\n while (currentDir !== path.parse(currentDir).root) {\n if (fs.existsSync(path.join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = path.dirname(currentDir);\n }\n return null;\n}\n\nfunction generateGlobalEmessageFile() {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n rl.question('You want to create EmessageGlobal file: (y) ', (answer) => {\n if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes' || answer === '') {\n const cwd = process.cwd();\n const projectRoot = findProjectRoot(cwd);\n\n if (!projectRoot) {\n console.error('Error: Could not find project root (package.json not found).');\n process.exit(1);\n }\n\n const tsconfigPath = path.join(projectRoot, 'tsconfig.json');\n const isTypeScriptProject = fs.existsSync(tsconfigPath);\n\n const fileExtension = isTypeScriptProject ? 'ts' : 'js';\n const content = isTypeScriptProject ? tsContent : jsContent;\n const outputFileName = `${fileName}.${fileExtension}`;\n const outputPath = path.join(projectRoot, outputFileName);\n\n if (fs.existsSync(outputPath)) {\n console.warn(`Warning: ${outputFileName} already exists. Skipping file creation.`);\n process.exit(0);\n }\n\n try {\n fs.writeFileSync(outputPath, content, 'utf8');\n console.log(`Successfully created ${outputFileName} in your project root.`);\n console.log('You can now configure global messages by editing this file.');\n } catch (error: any) {\n console.error(`Error creating ${outputFileName}:`, error.message);\n process.exit(1);\n }\n }\n rl.close();\n });\n}\n\ngenerateGlobalEmessageFile();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAoB;AACpB,WAAsB;AACtB,eAA0B;AAE1B,IAAM,WAAW;AACjB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAalB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAalB,SAAS,gBAAgB,UAAiC;AACtD,MAAI,aAAa;AACjB,SAAO,eAAoB,WAAM,UAAU,EAAE,MAAM;AAC/C,QAAO,cAAgB,UAAK,YAAY,cAAc,CAAC,GAAG;AACtD,aAAO;AAAA,IACX;AACA,iBAAkB,aAAQ,UAAU;AAAA,EACxC;AACA,SAAO;AACX;AAEA,SAAS,6BAA6B;AAClC,QAAM,KAAc,yBAAgB;AAAA,IAChC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EACpB,CAAC;AAED,KAAG,SAAS,gDAAgD,CAAC,WAAW;AACpE,QAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,SAAS,WAAW,IAAI;AACjF,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,cAAc,gBAAgB,GAAG;AAEvC,UAAI,CAAC,aAAa;AACd,gBAAQ,MAAM,8DAA8D;AAC5E,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAEA,YAAM,eAAoB,UAAK,aAAa,eAAe;AAC3D,YAAM,sBAAyB,cAAW,YAAY;AAEtD,YAAM,gBAAgB,sBAAsB,OAAO;AACnD,YAAM,UAAU,sBAAsB,YAAY;AAClD,YAAM,iBAAiB,GAAG,QAAQ,IAAI,aAAa;AACnD,YAAM,aAAkB,UAAK,aAAa,cAAc;AAExD,UAAO,cAAW,UAAU,GAAG;AAC3B,gBAAQ,KAAK,YAAY,cAAc,0CAA0C;AACjF,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAEA,UAAI;AACA,QAAG,iBAAc,YAAY,SAAS,MAAM;AAC5C,gBAAQ,IAAI,wBAAwB,cAAc,wBAAwB;AAC1E,gBAAQ,IAAI,6DAA6D;AAAA,MAC7E,SAAS,OAAY;AACjB,gBAAQ,MAAM,kBAAkB,cAAc,KAAK,MAAM,OAAO;AAChE,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAAA,IACJ;AACA,OAAG,MAAM;AAAA,EACb,CAAC;AACL;AAEA,2BAA2B;","names":[]}
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.mjs ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import * as readline from "readline";
7
+ var fileName = "EmessageGlobal";
8
+ var jsContent = `export const Emessage_global = [
9
+ {
10
+ GLOBAL_ERROR_MESSAGE: "Global error message.",
11
+ type:"war",
12
+ break:false,
13
+ toast: true
14
+ },
15
+ // {
16
+ // Add your custom global messages here.
17
+ // }
18
+ ];
19
+ `;
20
+ var tsContent = `export const Emessage_global = [
21
+ {
22
+ GLOBAL_ERROR_MESSAGE: "Global error message.",
23
+ type:"war",
24
+ break:false,
25
+ toast: true
26
+ },
27
+ // {
28
+ // Add your custom global messages here.
29
+ // }
30
+ ];
31
+ `;
32
+ function findProjectRoot(startDir) {
33
+ let currentDir = startDir;
34
+ while (currentDir !== path.parse(currentDir).root) {
35
+ if (fs.existsSync(path.join(currentDir, "package.json"))) {
36
+ return currentDir;
37
+ }
38
+ currentDir = path.dirname(currentDir);
39
+ }
40
+ return null;
41
+ }
42
+ function generateGlobalEmessageFile() {
43
+ const rl = readline.createInterface({
44
+ input: process.stdin,
45
+ output: process.stdout
46
+ });
47
+ rl.question("You want to create EmessageGlobal file: (y) ", (answer) => {
48
+ if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes" || answer === "") {
49
+ const cwd = process.cwd();
50
+ const projectRoot = findProjectRoot(cwd);
51
+ if (!projectRoot) {
52
+ console.error("Error: Could not find project root (package.json not found).");
53
+ process.exit(1);
54
+ }
55
+ const tsconfigPath = path.join(projectRoot, "tsconfig.json");
56
+ const isTypeScriptProject = fs.existsSync(tsconfigPath);
57
+ const fileExtension = isTypeScriptProject ? "ts" : "js";
58
+ const content = isTypeScriptProject ? tsContent : jsContent;
59
+ const outputFileName = `${fileName}.${fileExtension}`;
60
+ const outputPath = path.join(projectRoot, outputFileName);
61
+ if (fs.existsSync(outputPath)) {
62
+ console.warn(`Warning: ${outputFileName} already exists. Skipping file creation.`);
63
+ process.exit(0);
64
+ }
65
+ try {
66
+ fs.writeFileSync(outputPath, content, "utf8");
67
+ console.log(`Successfully created ${outputFileName} in your project root.`);
68
+ console.log("You can now configure global messages by editing this file.");
69
+ } catch (error) {
70
+ console.error(`Error creating ${outputFileName}:`, error.message);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ rl.close();
75
+ });
76
+ }
77
+ generateGlobalEmessageFile();
78
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as readline from 'readline';\n\nconst fileName = 'EmessageGlobal';\nconst jsContent = `export const Emessage_global = [\n {\n GLOBAL_ERROR_MESSAGE: \"Global error message.\",\n type:\"war\",\n break:false,\n toast: true\n },\n // {\n // Add your custom global messages here.\n // }\n];\n`;\n\nconst tsContent = `export const Emessage_global = [\n {\n GLOBAL_ERROR_MESSAGE: \"Global error message.\",\n type:\"war\",\n break:false,\n toast: true\n },\n // {\n // Add your custom global messages here.\n // }\n];\n`;\n\nfunction findProjectRoot(startDir: string): string | null {\n let currentDir = startDir;\n while (currentDir !== path.parse(currentDir).root) {\n if (fs.existsSync(path.join(currentDir, 'package.json'))) {\n return currentDir;\n }\n currentDir = path.dirname(currentDir);\n }\n return null;\n}\n\nfunction generateGlobalEmessageFile() {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n rl.question('You want to create EmessageGlobal file: (y) ', (answer) => {\n if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes' || answer === '') {\n const cwd = process.cwd();\n const projectRoot = findProjectRoot(cwd);\n\n if (!projectRoot) {\n console.error('Error: Could not find project root (package.json not found).');\n process.exit(1);\n }\n\n const tsconfigPath = path.join(projectRoot, 'tsconfig.json');\n const isTypeScriptProject = fs.existsSync(tsconfigPath);\n\n const fileExtension = isTypeScriptProject ? 'ts' : 'js';\n const content = isTypeScriptProject ? tsContent : jsContent;\n const outputFileName = `${fileName}.${fileExtension}`;\n const outputPath = path.join(projectRoot, outputFileName);\n\n if (fs.existsSync(outputPath)) {\n console.warn(`Warning: ${outputFileName} already exists. Skipping file creation.`);\n process.exit(0);\n }\n\n try {\n fs.writeFileSync(outputPath, content, 'utf8');\n console.log(`Successfully created ${outputFileName} in your project root.`);\n console.log('You can now configure global messages by editing this file.');\n } catch (error: any) {\n console.error(`Error creating ${outputFileName}:`, error.message);\n process.exit(1);\n }\n }\n rl.close();\n });\n}\n\ngenerateGlobalEmessageFile();\n"],"mappings":";;;AAEA,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,cAAc;AAE1B,IAAM,WAAW;AACjB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAalB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAalB,SAAS,gBAAgB,UAAiC;AACtD,MAAI,aAAa;AACjB,SAAO,eAAoB,WAAM,UAAU,EAAE,MAAM;AAC/C,QAAO,cAAgB,UAAK,YAAY,cAAc,CAAC,GAAG;AACtD,aAAO;AAAA,IACX;AACA,iBAAkB,aAAQ,UAAU;AAAA,EACxC;AACA,SAAO;AACX;AAEA,SAAS,6BAA6B;AAClC,QAAM,KAAc,yBAAgB;AAAA,IAChC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EACpB,CAAC;AAED,KAAG,SAAS,gDAAgD,CAAC,WAAW;AACpE,QAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,SAAS,WAAW,IAAI;AACjF,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,cAAc,gBAAgB,GAAG;AAEvC,UAAI,CAAC,aAAa;AACd,gBAAQ,MAAM,8DAA8D;AAC5E,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAEA,YAAM,eAAoB,UAAK,aAAa,eAAe;AAC3D,YAAM,sBAAyB,cAAW,YAAY;AAEtD,YAAM,gBAAgB,sBAAsB,OAAO;AACnD,YAAM,UAAU,sBAAsB,YAAY;AAClD,YAAM,iBAAiB,GAAG,QAAQ,IAAI,aAAa;AACnD,YAAM,aAAkB,UAAK,aAAa,cAAc;AAExD,UAAO,cAAW,UAAU,GAAG;AAC3B,gBAAQ,KAAK,YAAY,cAAc,0CAA0C;AACjF,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAEA,UAAI;AACA,QAAG,iBAAc,YAAY,SAAS,MAAM;AAC5C,gBAAQ,IAAI,wBAAwB,cAAc,wBAAwB;AAC1E,gBAAQ,IAAI,6DAA6D;AAAA,MAC7E,SAAS,OAAY;AACjB,gBAAQ,MAAM,kBAAkB,cAAc,KAAK,MAAM,OAAO;AAChE,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAAA,IACJ;AACA,OAAG,MAAM;AAAA,EACb,CAAC;AACL;AAEA,2BAA2B;","names":[]}
package/dist/index.cjs CHANGED
@@ -273,9 +273,16 @@ function parseConfig(config) {
273
273
  );
274
274
  return null;
275
275
  }
276
+ if (options.break === void 0) {
277
+ if (options.type === "war" || options.type === "log") {
278
+ options.break = false;
279
+ } else {
280
+ options.break = true;
281
+ }
282
+ }
276
283
  return { name, options: { ...options, message } };
277
284
  }
278
- function processEmessage(errorName, config) {
285
+ function processEmessage(errorName, config, errorToThrow) {
279
286
  const message = config.message;
280
287
  let consoleType;
281
288
  if (config.type === false) {
@@ -330,7 +337,7 @@ function processEmessage(errorName, config) {
330
337
  }
331
338
  if (config.break ?? true) {
332
339
  if (isBrowser()) {
333
- throw new Error(message);
340
+ throw errorToThrow || new Error(message);
334
341
  } else {
335
342
  process.exit(1);
336
343
  }
@@ -353,6 +360,7 @@ Emessage.global = function(...configs) {
353
360
  }
354
361
  };
355
362
  function showE(error) {
363
+ const errorForStack = new Error();
356
364
  let config = null;
357
365
  let errorName = null;
358
366
  if (typeof error === "string") {
@@ -376,7 +384,8 @@ function showE(error) {
376
384
  return;
377
385
  }
378
386
  if (config && errorName) {
379
- return processEmessage(errorName, config);
387
+ errorForStack.message = config.message;
388
+ return processEmessage(errorName, config, errorForStack);
380
389
  }
381
390
  }
382
391
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/store.ts","../src/utils.ts"],"sourcesContent":["import { individualMessageStore, globalMessageStore } from \"./store\";\r\nimport type {\r\n EmessageConfig,\r\n EmessageOptions,\r\n StoredEmessage,\r\n ToastConfig,\r\n MessageType,\r\n} from \"./types\";\r\nimport { isBrowser, showToast } from \"./utils\";\r\n\r\nfunction parseConfig(\r\n config: Record<string, any>\r\n): { name: string; options: StoredEmessage } | null {\r\n const options: EmessageOptions = {};\r\n let message: string | null = null;\r\n let name: string | null = null;\r\n const optionKeys = [\"type\", \"break\", \"toast\", \"returnEM\", \"callBack\"];\r\n\r\n for (const key in config) {\r\n if (Object.prototype.hasOwnProperty.call(config, key)) {\r\n if (optionKeys.includes(key)) {\r\n (options as any)[key] = config[key];\r\n } else {\r\n if (name !== null) {\r\n console.warn(\r\n `emessages: Found multiple potential error names in one config object. Using first one found: \"${name}\".`\r\n );\r\n continue;\r\n }\r\n name = key;\r\n message = String(config[key]);\r\n }\r\n }\r\n }\r\n\r\n if (name === null || message === null) {\r\n console.error(\r\n \"emessages: Invalid config object. Could not find error name and message.\",\r\n config\r\n );\r\n return null;\r\n }\r\n\r\n return { name, options: { ...options, message } };\r\n}\r\n\r\nfunction processEmessage(\r\n errorName: string,\r\n config: StoredEmessage\r\n): string | void {\r\n const message = config.message;\r\n\r\n let consoleType: MessageType | false;\r\n if (config.type === false) {\r\n consoleType = false;\r\n } else if (config.type === true || config.type === undefined) {\r\n consoleType = \"err\";\r\n } else {\r\n consoleType = config.type;\r\n }\r\n\r\n // 1. Console log\r\n if (consoleType) {\r\n if (isBrowser()) {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(message);\r\n break;\r\n case \"war\":\r\n console.warn(message);\r\n break;\r\n case \"err\":\r\n console.error(message);\r\n break;\r\n }\r\n } else {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(`\\x1b[30;47m ${message} \\x1b[0m`);\r\n break;\r\n case \"war\":\r\n console.warn(`\\x1b[37;43m ${message} \\x1b[0m`);\r\n break;\r\n case \"err\":\r\n console.error(`\\x1b[37;41m ${message} \\x1b[0m`);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // 2. Toast notification\r\n if (config.toast && isBrowser()) {\r\n showToast(message, config.toast, consoleType as MessageType);\r\n }\r\n\r\n // 3. Callback\r\n if (config.callBack) {\r\n try {\r\n config.callBack();\r\n } catch (e: any) {\r\n console.error(\r\n `emessages: Error in callBack for \"${errorName}\":`,\r\n e.message\r\n );\r\n }\r\n }\r\n\r\n // 4. Return error message\r\n if (config.returnEM) {\r\n return message;\r\n }\r\n\r\n // 5. Break execution\r\n if (config.break ?? true) {\r\n if (isBrowser()) {\r\n throw new Error(message);\r\n } else {\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nexport function Emessage(...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n individualMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n}\r\n\r\nEmessage.global = function (...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n globalMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n};\r\n\r\nexport function showE(error: string | Record<string, any>): string | void {\r\n let config: StoredEmessage | null = null;\r\n let errorName: string | null = null;\r\n\r\n if (typeof error === \"string\") {\r\n errorName = error;\r\n config =\r\n individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;\r\n if (!config) {\r\n console.error(`emessages: Error \"${error}\" not found.`);\r\n return;\r\n }\r\n } else if (typeof error === \"object\" && error !== null) {\r\n const parsed = parseConfig(error);\r\n if (parsed) {\r\n errorName = parsed.name;\r\n config = parsed.options;\r\n } else {\r\n console.error(\"emessages: Invalid object passed to showE.\");\r\n return;\r\n }\r\n } else {\r\n console.error(\"emessages: Invalid argument passed to showE.\");\r\n return;\r\n }\r\n\r\n if (config && errorName) {\r\n return processEmessage(errorName, config);\r\n }\r\n}\r\n","import type { StoredEmessage } from \"./types\";\r\n\r\nexport const individualMessageStore = new Map<string, StoredEmessage>();\r\nexport const globalMessageStore = new Map<string, StoredEmessage>();\r\n","import { ToastConfig, MessageType } from \"./types\";\r\n\r\nexport function isBrowser(): boolean {\r\n return typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\r\n}\r\n\r\n\r\n/**\r\n * Removes a toast element from the DOM with a fade-out transition.\r\n * @param toastElement The toast element to remove.\r\n */\r\nfunction removeToastElement(toastElement: HTMLElement | null) {\r\n if (!toastElement || !toastElement.parentElement) return;\r\n\r\n toastElement.classList.remove(\"visible\");\r\n // Remove the element after the transition ends to allow for animation\r\n toastElement.addEventListener(\"transitionend\", () => {\r\n const container = toastElement.parentElement;\r\n if (container) {\r\n container.removeChild(toastElement);\r\n // If the container is now empty, remove it from the DOM\r\n if (container.childElementCount === 0 && container.parentElement) {\r\n container.parentElement.removeChild(container);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Initializes the global API for emessages, like window.emessages.closeToast\r\n */\r\nfunction initializeGlobalApi() {\r\n if (!isBrowser()) return;\r\n\r\n // Ensure the global namespace exists\r\n if (!(window as any).emessages) {\r\n (window as any).emessages = {};\r\n }\r\n\r\n // Attach the closeToast function if it doesn't exist\r\n if (!(window as any).emessages.closeToast) {\r\n (window as any).emessages.closeToast = function (eventOrId: Event | string) {\r\n let toastElement: HTMLElement | null = null;\r\n\r\n if (typeof eventOrId === 'string') {\r\n // Find toast by ID\r\n toastElement = document.getElementById(eventOrId);\r\n } else if (eventOrId && eventOrId.target) {\r\n // Find toast by traversing from the event target\r\n toastElement = (eventOrId.target as HTMLElement).closest('.emessage-toast');\r\n }\r\n\r\n if (toastElement) {\r\n removeToastElement(toastElement);\r\n } else {\r\n console.warn('emessages: closeToast() was called but could not find a toast element to close.');\r\n }\r\n };\r\n }\r\n}\r\n\r\n// Initialize the global API when the module is loaded\r\ninitializeGlobalApi();\r\n\r\n\r\n// Function to inject CSS for toasts\r\nfunction injectToastStyles() {\r\n if (!isBrowser()) return;\r\n\r\n const styleId = \"emessages-toast-styles\";\r\n if (document.getElementById(styleId)) {\r\n return; // Styles already injected\r\n }\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = styleId;\r\n style.innerHTML = `\r\n .emessages-toast-container {\r\n position: fixed;\r\n display: flex;\r\n flex-direction: column;\r\n padding: 10px;\r\n pointer-events: none;\r\n z-index: 9999;\r\n box-sizing: border-box;\r\n }\r\n\r\n /* Positioning for containers */\r\n .emessages-toast-container.top-left { top: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.top-center { top: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.top-right { top: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.bottom-left { bottom: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.bottom-center { bottom: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.bottom-right { bottom: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.center { top: 50%; left: 50%; transform: translate(-50%, -50%); align-items: center; }\r\n .emessages-toast-container.center-left { top: 50%; left: 0; transform: translateY(-50%); align-items: flex-start; }\r\n .emessages-toast-container.center-right { top: 50%; right: 0; transform: translateY(-50%); align-items: flex-end; }\r\n\r\n\r\n .emessage-toast {\r\n padding: 12px 18px;\r\n margin: 8px;\r\n border-radius: 6px;\r\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\r\n font-size: 14px;\r\n opacity: 0;\r\n transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;\r\n transform: translateY(20px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n pointer-events: all;\r\n max-width: 350px;\r\n word-break: break-word;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n gap: 10px;\r\n box-sizing: border-box;\r\n }\r\n\r\n .emessage-toast.visible {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n /* Default styles based on message type */\r\n .emessage-toast-err { background-color: #ef4444; color: white; } /* red-500 */\r\n .emessage-toast-war { background-color: #f59e0b; color: white; } /* amber-500 */\r\n .emessage-toast-log { background-color: #ffffff; color: #1f2937; border: 1px solid #e5e7eb; } /* white, gray-800 text, gray-200 border */\r\n\r\n .emessage-toast-message {\r\n flex-grow: 1;\r\n }\r\n\r\n .emessage-toast-close {\r\n background: none;\r\n border: none;\r\n color: inherit;\r\n font-size: 20px;\r\n font-weight: bold;\r\n cursor: pointer;\r\n line-height: 1;\r\n opacity: 0.7;\r\n padding: 0;\r\n margin-left: 15px;\r\n }\r\n .emessage-toast-close:hover {\r\n opacity: 1;\r\n }\r\n .emessage-toast-close:focus,\r\n .emessage-toast-close:focus-visible {\r\n outline: none;\r\n }\r\n `;\r\n // Prepend styles to give user stylesheets higher priority\r\n document.head.insertBefore(style, document.head.firstChild);\r\n}\r\n\r\n// Function to get or create a specific toast container for a position\r\nfunction getOrCreateToastContainer(position: string): HTMLElement {\r\n // Normalize position string to handle variants like \"top\" -> \"top-center\"\r\n const positionMap: Record<string, string> = {\r\n top: \"top-center\",\r\n bottom: \"bottom-center\",\r\n left: \"center-left\",\r\n right: \"center-right\",\r\n center: \"center\",\r\n \"top-right\": \"top-right\",\r\n \"top-left\": \"top-left\",\r\n \"top-center\": \"top-center\",\r\n \"bottom-right\": \"bottom-right\",\r\n \"bottom-left\": \"bottom-left\",\r\n \"bottom-center\": \"bottom-center\",\r\n \"center-left\": \"center-left\",\r\n \"center-right\": \"center-right\",\r\n };\r\n\r\n const normalizedPosition = positionMap[position.toLowerCase().replace(/\\s/g, \"-\")] || \"top-right\";\r\n const containerId = `emessages-toast-container-${normalizedPosition}`;\r\n let container = document.getElementById(containerId);\r\n\r\n if (!container) {\r\n container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.className = `emessages-toast-container ${normalizedPosition}`;\r\n document.body.appendChild(container);\r\n }\r\n return container;\r\n}\r\n\r\n\r\nexport function showToast(\r\n message: string,\r\n toastOptions: boolean | ToastConfig,\r\n messageType: MessageType = \"log\"\r\n): void {\r\n if (!isBrowser()) {\r\n return;\r\n }\r\n\r\n injectToastStyles();\r\n\r\n const config: ToastConfig = typeof toastOptions === \"object\" ? toastOptions : {};\r\n\r\n let {\r\n message: customMessage,\r\n style: customStyle,\r\n class: customClass,\r\n position = \"top-right\",\r\n stay = false,\r\n duration = 3000,\r\n delay = 0,\r\n } = config;\r\n \r\n const toast = document.createElement(\"div\");\r\n // Assign a unique ID for programmatic closing\r\n toast.id = `emessage-toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n \r\n // Base class is applied first\r\n let toastClasses = ['emessage-toast'];\r\n \r\n // Add default type class. We use a separate class to avoid specificity conflicts.\r\n toastClasses.push(`emessage-toast-${messageType}`);\r\n \r\n // Add custom classes. These can now override the default type styles if they have the same specificity.\r\n if (customClass) {\r\n toastClasses.push(...customClass.split(' ').filter(c => c));\r\n }\r\n \r\n toast.className = toastClasses.join(' ');\r\n \r\n // Apply custom inline style from config (highest priority)\r\n if (customStyle) {\r\n toast.style.cssText += customStyle;\r\n }\r\n \r\n // Create a dedicated element for the message to avoid conflicts with the close button\r\n const messageElement = document.createElement('div');\r\n messageElement.className = 'emessage-toast-message';\r\n \r\n // Check if customMessage is a React element or other object, which is invalid.\r\n if (typeof customMessage === 'object' && customMessage !== null) {\r\n console.warn('emessages: The `toast.message` property received an object (likely a React component), but it only accepts an HTML string. Please pass a string of HTML to render it correctly. Falling back to the default message.');\r\n customMessage = undefined; // Use the default message instead\r\n }\r\n \r\n messageElement.innerHTML = customMessage || message;\r\n toast.appendChild(messageElement);\r\n \r\n \r\n // Add close button (always add for accessibility, but control removal logic)\r\n const closeButton = document.createElement(\"button\");\r\n closeButton.className = \"emessage-toast-close\";\r\n closeButton.innerHTML = \"&times;\";\r\n closeButton.setAttribute(\"aria-label\", \"Close\");\r\n closeButton.onclick = () => removeToastElement(toast);\r\n toast.appendChild(closeButton);\r\n \r\n const container = getOrCreateToastContainer(position);\r\n \r\n // Delay the appearance of the toast\r\n setTimeout(() => {\r\n // For bottom-positioned toasts, insert at the top of the container\r\n if (position.includes('bottom')) {\r\n container.prepend(toast);\r\n } else {\r\n container.appendChild(toast);\r\n }\r\n \r\n // Allow the element to be in the DOM before transitioning\r\n requestAnimationFrame(() => {\r\n toast.classList.add(\"visible\");\r\n });\r\n }, delay);\r\n \r\n // Set up auto-hide if not staying\r\n if (!stay) {\r\n const hideTimeout = setTimeout(() => removeToastElement(toast), delay + duration);\r\n // Optional: pause on hover\r\n toast.addEventListener('mouseenter', () => clearTimeout(hideTimeout));\r\n toast.addEventListener('mouseleave', () => {\r\n if (!stay) {\r\n setTimeout(() => removeToastElement(toast), 1000); // Give some time before hiding on mouse leave\r\n }\r\n });\r\n }}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/store.ts","../src/utils.ts"],"sourcesContent":["import { individualMessageStore, globalMessageStore } from \"./store\";\r\nimport type {\r\n EmessageConfig,\r\n EmessageOptions,\r\n StoredEmessage,\r\n ToastConfig,\r\n MessageType,\r\n} from \"./types\";\r\nimport { isBrowser, showToast } from \"./utils\";\r\n\r\nfunction parseConfig(\r\n config: Record<string, any>\r\n): { name: string; options: StoredEmessage } | null {\r\n const options: EmessageOptions = {};\r\n let message: string | null = null;\r\n let name: string | null = null;\r\n const optionKeys = [\"type\", \"break\", \"toast\", \"returnEM\", \"callBack\"];\r\n\r\n for (const key in config) {\r\n if (Object.prototype.hasOwnProperty.call(config, key)) {\r\n if (optionKeys.includes(key)) {\r\n (options as any)[key] = config[key];\r\n } else {\r\n if (name !== null) {\r\n console.warn(\r\n `emessages: Found multiple potential error names in one config object. Using first one found: \"${name}\".`\r\n );\r\n continue;\r\n }\r\n name = key;\r\n message = String(config[key]);\r\n }\r\n }\r\n }\r\n\r\n if (name === null || message === null) {\r\n console.error(\r\n \"emessages: Invalid config object. Could not find error name and message.\",\r\n config\r\n );\r\n return null;\r\n }\r\n\r\n // Apply default for 'break' if not explicitly set\r\n if (options.break === undefined) {\r\n if (options.type === \"war\" || options.type === \"log\") {\r\n options.break = false;\r\n } else {\r\n // Default for 'err' type or if type is not specified\r\n options.break = true;\r\n }\r\n }\r\n\r\n return { name, options: { ...options, message } };\r\n}\r\n\r\nfunction processEmessage(\r\n errorName: string,\r\n config: StoredEmessage,\r\n errorToThrow?: Error\r\n): string | void {\r\n const message = config.message;\r\n\r\n let consoleType: MessageType | false;\r\n if (config.type === false) {\r\n consoleType = false;\r\n } else if (config.type === true || config.type === undefined) {\r\n consoleType = \"err\";\r\n } else {\r\n consoleType = config.type;\r\n }\r\n\r\n // 1. Console log\r\n if (consoleType) {\r\n if (isBrowser()) {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(message);\r\n break;\r\n case \"war\":\r\n console.warn(message);\r\n break;\r\n case \"err\":\r\n console.error(message);\r\n break;\r\n }\r\n } else {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(`\\x1b[30;47m ${message} \\x1b[0m`);\r\n break;\r\n case \"war\":\r\n console.warn(`\\x1b[37;43m ${message} \\x1b[0m`);\r\n break;\r\n case \"err\":\r\n console.error(`\\x1b[37;41m ${message} \\x1b[0m`);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // 2. Toast notification\r\n if (config.toast && isBrowser()) {\r\n showToast(message, config.toast, consoleType as MessageType);\r\n }\r\n\r\n // 3. Callback\r\n if (config.callBack) {\r\n try {\r\n config.callBack();\r\n } catch (e: any) {\r\n console.error(\r\n `emessages: Error in callBack for \"${errorName}\":`,\r\n e.message\r\n );\r\n }\r\n }\r\n\r\n // 4. Return error message\r\n if (config.returnEM) {\r\n return message;\r\n }\r\n\r\n // 5. Break execution\r\n if (config.break ?? true) {\r\n if (isBrowser()) {\r\n throw errorToThrow || new Error(message);\r\n } else {\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nexport function Emessage(...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n individualMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n}\r\n\r\nEmessage.global = function (...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n globalMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n};\r\n\r\nexport function showE(error: string | Record<string, any>): string | void {\r\n const errorForStack = new Error();\r\n let config: StoredEmessage | null = null;\r\n let errorName: string | null = null;\r\n\r\n if (typeof error === \"string\") {\r\n errorName = error;\r\n config =\r\n individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;\r\n if (!config) {\r\n console.error(`emessages: Error \"${error}\" not found.`);\r\n return;\r\n }\r\n } else if (typeof error === \"object\" && error !== null) {\r\n const parsed = parseConfig(error);\r\n if (parsed) {\r\n errorName = parsed.name;\r\n config = parsed.options;\r\n } else {\r\n console.error(\"emessages: Invalid object passed to showE.\");\r\n return;\r\n }\r\n } else {\r\n console.error(\"emessages: Invalid argument passed to showE.\");\r\n return;\r\n }\r\n\r\n if (config && errorName) {\r\n errorForStack.message = config.message;\r\n return processEmessage(errorName, config, errorForStack);\r\n }\r\n}\r\n","import type { StoredEmessage } from \"./types\";\r\n\r\nexport const individualMessageStore = new Map<string, StoredEmessage>();\r\nexport const globalMessageStore = new Map<string, StoredEmessage>();\r\n","import { ToastConfig, MessageType } from \"./types\";\r\n\r\nexport function isBrowser(): boolean {\r\n return typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\r\n}\r\n\r\n\r\n/**\r\n * Removes a toast element from the DOM with a fade-out transition.\r\n * @param toastElement The toast element to remove.\r\n */\r\nfunction removeToastElement(toastElement: HTMLElement | null) {\r\n if (!toastElement || !toastElement.parentElement) return;\r\n\r\n toastElement.classList.remove(\"visible\");\r\n // Remove the element after the transition ends to allow for animation\r\n toastElement.addEventListener(\"transitionend\", () => {\r\n const container = toastElement.parentElement;\r\n if (container) {\r\n container.removeChild(toastElement);\r\n // If the container is now empty, remove it from the DOM\r\n if (container.childElementCount === 0 && container.parentElement) {\r\n container.parentElement.removeChild(container);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Initializes the global API for emessages, like window.emessages.closeToast\r\n */\r\nfunction initializeGlobalApi() {\r\n if (!isBrowser()) return;\r\n\r\n // Ensure the global namespace exists\r\n if (!(window as any).emessages) {\r\n (window as any).emessages = {};\r\n }\r\n\r\n // Attach the closeToast function if it doesn't exist\r\n if (!(window as any).emessages.closeToast) {\r\n (window as any).emessages.closeToast = function (eventOrId: Event | string) {\r\n let toastElement: HTMLElement | null = null;\r\n\r\n if (typeof eventOrId === 'string') {\r\n // Find toast by ID\r\n toastElement = document.getElementById(eventOrId);\r\n } else if (eventOrId && eventOrId.target) {\r\n // Find toast by traversing from the event target\r\n toastElement = (eventOrId.target as HTMLElement).closest('.emessage-toast');\r\n }\r\n\r\n if (toastElement) {\r\n removeToastElement(toastElement);\r\n } else {\r\n console.warn('emessages: closeToast() was called but could not find a toast element to close.');\r\n }\r\n };\r\n }\r\n}\r\n\r\n// Initialize the global API when the module is loaded\r\ninitializeGlobalApi();\r\n\r\n\r\n// Function to inject CSS for toasts\r\nfunction injectToastStyles() {\r\n if (!isBrowser()) return;\r\n\r\n const styleId = \"emessages-toast-styles\";\r\n if (document.getElementById(styleId)) {\r\n return; // Styles already injected\r\n }\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = styleId;\r\n style.innerHTML = `\r\n .emessages-toast-container {\r\n position: fixed;\r\n display: flex;\r\n flex-direction: column;\r\n padding: 10px;\r\n pointer-events: none;\r\n z-index: 9999;\r\n box-sizing: border-box;\r\n }\r\n\r\n /* Positioning for containers */\r\n .emessages-toast-container.top-left { top: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.top-center { top: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.top-right { top: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.bottom-left { bottom: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.bottom-center { bottom: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.bottom-right { bottom: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.center { top: 50%; left: 50%; transform: translate(-50%, -50%); align-items: center; }\r\n .emessages-toast-container.center-left { top: 50%; left: 0; transform: translateY(-50%); align-items: flex-start; }\r\n .emessages-toast-container.center-right { top: 50%; right: 0; transform: translateY(-50%); align-items: flex-end; }\r\n\r\n\r\n .emessage-toast {\r\n padding: 12px 18px;\r\n margin: 8px;\r\n border-radius: 6px;\r\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\r\n font-size: 14px;\r\n opacity: 0;\r\n transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;\r\n transform: translateY(20px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n pointer-events: all;\r\n max-width: 350px;\r\n word-break: break-word;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n gap: 10px;\r\n box-sizing: border-box;\r\n }\r\n\r\n .emessage-toast.visible {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n /* Default styles based on message type */\r\n .emessage-toast-err { background-color: #ef4444; color: white; } /* red-500 */\r\n .emessage-toast-war { background-color: #f59e0b; color: white; } /* amber-500 */\r\n .emessage-toast-log { background-color: #ffffff; color: #1f2937; border: 1px solid #e5e7eb; } /* white, gray-800 text, gray-200 border */\r\n\r\n .emessage-toast-message {\r\n flex-grow: 1;\r\n }\r\n\r\n .emessage-toast-close {\r\n background: none;\r\n border: none;\r\n color: inherit;\r\n font-size: 20px;\r\n font-weight: bold;\r\n cursor: pointer;\r\n line-height: 1;\r\n opacity: 0.7;\r\n padding: 0;\r\n margin-left: 15px;\r\n }\r\n .emessage-toast-close:hover {\r\n opacity: 1;\r\n }\r\n .emessage-toast-close:focus,\r\n .emessage-toast-close:focus-visible {\r\n outline: none;\r\n }\r\n `;\r\n // Prepend styles to give user stylesheets higher priority\r\n document.head.insertBefore(style, document.head.firstChild);\r\n}\r\n\r\n// Function to get or create a specific toast container for a position\r\nfunction getOrCreateToastContainer(position: string): HTMLElement {\r\n // Normalize position string to handle variants like \"top\" -> \"top-center\"\r\n const positionMap: Record<string, string> = {\r\n top: \"top-center\",\r\n bottom: \"bottom-center\",\r\n left: \"center-left\",\r\n right: \"center-right\",\r\n center: \"center\",\r\n \"top-right\": \"top-right\",\r\n \"top-left\": \"top-left\",\r\n \"top-center\": \"top-center\",\r\n \"bottom-right\": \"bottom-right\",\r\n \"bottom-left\": \"bottom-left\",\r\n \"bottom-center\": \"bottom-center\",\r\n \"center-left\": \"center-left\",\r\n \"center-right\": \"center-right\",\r\n };\r\n\r\n const normalizedPosition = positionMap[position.toLowerCase().replace(/\\s/g, \"-\")] || \"top-right\";\r\n const containerId = `emessages-toast-container-${normalizedPosition}`;\r\n let container = document.getElementById(containerId);\r\n\r\n if (!container) {\r\n container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.className = `emessages-toast-container ${normalizedPosition}`;\r\n document.body.appendChild(container);\r\n }\r\n return container;\r\n}\r\n\r\n\r\nexport function showToast(\r\n message: string,\r\n toastOptions: boolean | ToastConfig,\r\n messageType: MessageType = \"log\"\r\n): void {\r\n if (!isBrowser()) {\r\n return;\r\n }\r\n\r\n injectToastStyles();\r\n\r\n const config: ToastConfig = typeof toastOptions === \"object\" ? toastOptions : {};\r\n\r\n let {\r\n message: customMessage,\r\n style: customStyle,\r\n class: customClass,\r\n position = \"top-right\",\r\n stay = false,\r\n duration = 3000,\r\n delay = 0,\r\n } = config;\r\n \r\n const toast = document.createElement(\"div\");\r\n // Assign a unique ID for programmatic closing\r\n toast.id = `emessage-toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n \r\n // Base class is applied first\r\n let toastClasses = ['emessage-toast'];\r\n \r\n // Add default type class. We use a separate class to avoid specificity conflicts.\r\n toastClasses.push(`emessage-toast-${messageType}`);\r\n \r\n // Add custom classes. These can now override the default type styles if they have the same specificity.\r\n if (customClass) {\r\n toastClasses.push(...customClass.split(' ').filter(c => c));\r\n }\r\n \r\n toast.className = toastClasses.join(' ');\r\n \r\n // Apply custom inline style from config (highest priority)\r\n if (customStyle) {\r\n toast.style.cssText += customStyle;\r\n }\r\n \r\n // Create a dedicated element for the message to avoid conflicts with the close button\r\n const messageElement = document.createElement('div');\r\n messageElement.className = 'emessage-toast-message';\r\n \r\n // Check if customMessage is a React element or other object, which is invalid.\r\n if (typeof customMessage === 'object' && customMessage !== null) {\r\n console.warn('emessages: The `toast.message` property received an object (likely a React component), but it only accepts an HTML string. Please pass a string of HTML to render it correctly. Falling back to the default message.');\r\n customMessage = undefined; // Use the default message instead\r\n }\r\n \r\n messageElement.innerHTML = customMessage || message;\r\n toast.appendChild(messageElement);\r\n \r\n \r\n // Add close button (always add for accessibility, but control removal logic)\r\n const closeButton = document.createElement(\"button\");\r\n closeButton.className = \"emessage-toast-close\";\r\n closeButton.innerHTML = \"&times;\";\r\n closeButton.setAttribute(\"aria-label\", \"Close\");\r\n closeButton.onclick = () => removeToastElement(toast);\r\n toast.appendChild(closeButton);\r\n \r\n const container = getOrCreateToastContainer(position);\r\n \r\n // Delay the appearance of the toast\r\n setTimeout(() => {\r\n // For bottom-positioned toasts, insert at the top of the container\r\n if (position.includes('bottom')) {\r\n container.prepend(toast);\r\n } else {\r\n container.appendChild(toast);\r\n }\r\n \r\n // Allow the element to be in the DOM before transitioning\r\n requestAnimationFrame(() => {\r\n toast.classList.add(\"visible\");\r\n });\r\n }, delay);\r\n \r\n // Set up auto-hide if not staying\r\n if (!stay) {\r\n const hideTimeout = setTimeout(() => removeToastElement(toast), delay + duration);\r\n // Optional: pause on hover\r\n toast.addEventListener('mouseenter', () => clearTimeout(hideTimeout));\r\n toast.addEventListener('mouseleave', () => {\r\n if (!stay) {\r\n setTimeout(() => removeToastElement(toast), 1000); // Give some time before hiding on mouse leave\r\n }\r\n });\r\n }}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,yBAAyB,oBAAI,IAA4B;AAC/D,IAAM,qBAAqB,oBAAI,IAA4B;;;ACD3D,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW,eAAe,OAAO,OAAO,aAAa;AACrE;AAOA,SAAS,mBAAmB,cAAkC;AAC5D,MAAI,CAAC,gBAAgB,CAAC,aAAa,cAAe;AAElD,eAAa,UAAU,OAAO,SAAS;AAEvC,eAAa,iBAAiB,iBAAiB,MAAM;AACnD,UAAM,YAAY,aAAa;AAC/B,QAAI,WAAW;AACb,gBAAU,YAAY,YAAY;AAElC,UAAI,UAAU,sBAAsB,KAAK,UAAU,eAAe;AAChE,kBAAU,cAAc,YAAY,SAAS;AAAA,MAC/C;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKA,SAAS,sBAAsB;AAC7B,MAAI,CAAC,UAAU,EAAG;AAGlB,MAAI,CAAE,OAAe,WAAW;AAC9B,IAAC,OAAe,YAAY,CAAC;AAAA,EAC/B;AAGA,MAAI,CAAE,OAAe,UAAU,YAAY;AACzC,IAAC,OAAe,UAAU,aAAa,SAAU,WAA2B;AAC1E,UAAI,eAAmC;AAEvC,UAAI,OAAO,cAAc,UAAU;AAEjC,uBAAe,SAAS,eAAe,SAAS;AAAA,MAClD,WAAW,aAAa,UAAU,QAAQ;AAExC,uBAAgB,UAAU,OAAuB,QAAQ,iBAAiB;AAAA,MAC5E;AAEA,UAAI,cAAc;AAChB,2BAAmB,YAAY;AAAA,MACjC,OAAO;AACL,gBAAQ,KAAK,iFAAiF;AAAA,MAChG;AAAA,IACF;AAAA,EACF;AACF;AAGA,oBAAoB;AAIpB,SAAS,oBAAoB;AAC3B,MAAI,CAAC,UAAU,EAAG;AAElB,QAAM,UAAU;AAChB,MAAI,SAAS,eAAe,OAAO,GAAG;AACpC;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,KAAK;AACX,QAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8ElB,WAAS,KAAK,aAAa,OAAO,SAAS,KAAK,UAAU;AAC5D;AAGA,SAAS,0BAA0B,UAA+B;AAEhE,QAAM,cAAsC;AAAA,IAC1C,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AAEA,QAAM,qBAAqB,YAAY,SAAS,YAAY,EAAE,QAAQ,OAAO,GAAG,CAAC,KAAK;AACtF,QAAM,cAAc,6BAA6B,kBAAkB;AACnE,MAAI,YAAY,SAAS,eAAe,WAAW;AAEnD,MAAI,CAAC,WAAW;AACd,gBAAY,SAAS,cAAc,KAAK;AACxC,cAAU,KAAK;AACf,cAAU,YAAY,6BAA6B,kBAAkB;AACrE,aAAS,KAAK,YAAY,SAAS;AAAA,EACrC;AACA,SAAO;AACT;AAGO,SAAS,UACd,SACA,cACA,cAA2B,OACrB;AACN,MAAI,CAAC,UAAU,GAAG;AAChB;AAAA,EACF;AAEA,oBAAkB;AAElB,QAAM,SAAsB,OAAO,iBAAiB,WAAW,eAAe,CAAC;AAE7E,MAAI;AAAA,IACF,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ;AAAA,EACV,IAAI;AAEJ,QAAM,QAAQ,SAAS,cAAc,KAAK;AAE1C,QAAM,KAAK,kBAAkB,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AAGlF,MAAI,eAAe,CAAC,gBAAgB;AAGpC,eAAa,KAAK,kBAAkB,WAAW,EAAE;AAGjD,MAAI,aAAa;AACf,iBAAa,KAAK,GAAG,YAAY,MAAM,GAAG,EAAE,OAAO,OAAK,CAAC,CAAC;AAAA,EAC5D;AAEA,QAAM,YAAY,aAAa,KAAK,GAAG;AAGvC,MAAI,aAAa;AACf,UAAM,MAAM,WAAW;AAAA,EACzB;AAGA,QAAM,iBAAiB,SAAS,cAAc,KAAK;AACnD,iBAAe,YAAY;AAG3B,MAAI,OAAO,kBAAkB,YAAY,kBAAkB,MAAM;AAC7D,YAAQ,KAAK,sNAAsN;AACnO,oBAAgB;AAAA,EACpB;AAEA,iBAAe,YAAY,iBAAiB;AAC5C,QAAM,YAAY,cAAc;AAIhC,QAAM,cAAc,SAAS,cAAc,QAAQ;AACnD,cAAY,YAAY;AACxB,cAAY,YAAY;AACxB,cAAY,aAAa,cAAc,OAAO;AAC9C,cAAY,UAAU,MAAM,mBAAmB,KAAK;AACpD,QAAM,YAAY,WAAW;AAE7B,QAAM,YAAY,0BAA0B,QAAQ;AAGpD,aAAW,MAAM;AAEf,QAAI,SAAS,SAAS,QAAQ,GAAG;AAC7B,gBAAU,QAAQ,KAAK;AAAA,IAC3B,OAAO;AACH,gBAAU,YAAY,KAAK;AAAA,IAC/B;AAGA,0BAAsB,MAAM;AACxB,YAAM,UAAU,IAAI,SAAS;AAAA,IACjC,CAAC;AAAA,EACH,GAAG,KAAK;AAGR,MAAI,CAAC,MAAM;AACT,UAAM,cAAc,WAAW,MAAM,mBAAmB,KAAK,GAAG,QAAQ,QAAQ;AAEhF,UAAM,iBAAiB,cAAc,MAAM,aAAa,WAAW,CAAC;AACpE,UAAM,iBAAiB,cAAc,MAAM;AACvC,UAAI,CAAC,MAAM;AACP,mBAAW,MAAM,mBAAmB,KAAK,GAAG,GAAI;AAAA,MACpD;AAAA,IACJ,CAAC;AAAA,EACH;AAAC;;;AFlRL,SAAS,YACP,QACkD;AAClD,QAAM,UAA2B,CAAC;AAClC,MAAI,UAAyB;AAC7B,MAAI,OAAsB;AAC1B,QAAM,aAAa,CAAC,QAAQ,SAAS,SAAS,YAAY,UAAU;AAEpE,aAAW,OAAO,QAAQ;AACxB,QAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,GAAG;AACrD,UAAI,WAAW,SAAS,GAAG,GAAG;AAC5B,QAAC,QAAgB,GAAG,IAAI,OAAO,GAAG;AAAA,MACpC,OAAO;AACL,YAAI,SAAS,MAAM;AACjB,kBAAQ;AAAA,YACN,iGAAiG,IAAI;AAAA,UACvG;AACA;AAAA,QACF;AACA,eAAO;AACP,kBAAU,OAAO,OAAO,GAAG,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ,YAAY,MAAM;AACrC,YAAQ;AAAA,MACN;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,UAAU,QAAW;AAC/B,QAAI,QAAQ,SAAS,SAAS,QAAQ,SAAS,OAAO;AACpD,cAAQ,QAAQ;AAAA,IAClB,OAAO;AAEL,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,EAAE,GAAG,SAAS,QAAQ,EAAE;AAClD;AAEA,SAAS,gBACP,WACA,QACA,cACe;AACf,QAAM,UAAU,OAAO;AAEvB,MAAI;AACJ,MAAI,OAAO,SAAS,OAAO;AACzB,kBAAc;AAAA,EAChB,WAAW,OAAO,SAAS,QAAQ,OAAO,SAAS,QAAW;AAC5D,kBAAc;AAAA,EAChB,OAAO;AACL,kBAAc,OAAO;AAAA,EACvB;AAGA,MAAI,aAAa;AACf,QAAI,UAAU,GAAG;AACf,cAAQ,aAAa;AAAA,QACnB,KAAK;AACH,kBAAQ,IAAI,OAAO;AACnB;AAAA,QACF,KAAK;AACH,kBAAQ,KAAK,OAAO;AACpB;AAAA,QACF,KAAK;AACH,kBAAQ,MAAM,OAAO;AACrB;AAAA,MACJ;AAAA,IACF,OAAO;AACL,cAAQ,aAAa;AAAA,QACnB,KAAK;AACH,kBAAQ,IAAI,eAAe,OAAO,UAAU;AAC5C;AAAA,QACF,KAAK;AACH,kBAAQ,KAAK,eAAe,OAAO,UAAU;AAC7C;AAAA,QACF,KAAK;AACH,kBAAQ,MAAM,eAAe,OAAO,UAAU;AAC9C;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,UAAU,GAAG;AAC/B,cAAU,SAAS,OAAO,OAAO,WAA0B;AAAA,EAC7D;AAGA,MAAI,OAAO,UAAU;AACnB,QAAI;AACF,aAAO,SAAS;AAAA,IAClB,SAAS,GAAQ;AACf,cAAQ;AAAA,QACN,qCAAqC,SAAS;AAAA,QAC9C,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,UAAU;AACnB,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,SAAS,MAAM;AACxB,QAAI,UAAU,GAAG;AACf,YAAM,gBAAgB,IAAI,MAAM,OAAO;AAAA,IACzC,OAAO;AACL,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AAEO,SAAS,YAAY,SAA2B;AACrD,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,YAAY,MAAM;AACjC,QAAI,QAAQ;AACV,6BAAuB,IAAI,OAAO,MAAM,OAAO,OAAO;AAAA,IACxD;AAAA,EACF;AACF;AAEA,SAAS,SAAS,YAAa,SAA2B;AACxD,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,YAAY,MAAM;AACjC,QAAI,QAAQ;AACV,yBAAmB,IAAI,OAAO,MAAM,OAAO,OAAO;AAAA,IACpD;AAAA,EACF;AACF;AAEO,SAAS,MAAM,OAAoD;AACxE,QAAM,gBAAgB,IAAI,MAAM;AAChC,MAAI,SAAgC;AACpC,MAAI,YAA2B;AAE/B,MAAI,OAAO,UAAU,UAAU;AAC7B,gBAAY;AACZ,aACE,uBAAuB,IAAI,KAAK,KAAK,mBAAmB,IAAI,KAAK,KAAK;AACxE,QAAI,CAAC,QAAQ;AACX,cAAQ,MAAM,qBAAqB,KAAK,cAAc;AACtD;AAAA,IACF;AAAA,EACF,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACtD,UAAM,SAAS,YAAY,KAAK;AAChC,QAAI,QAAQ;AACV,kBAAY,OAAO;AACnB,eAAS,OAAO;AAAA,IAClB,OAAO;AACL,cAAQ,MAAM,4CAA4C;AAC1D;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,MAAM,8CAA8C;AAC5D;AAAA,EACF;AAEA,MAAI,UAAU,WAAW;AACvB,kBAAc,UAAU,OAAO;AAC/B,WAAO,gBAAgB,WAAW,QAAQ,aAAa;AAAA,EACzD;AACF;","names":[]}
package/dist/index.mjs CHANGED
@@ -246,9 +246,16 @@ function parseConfig(config) {
246
246
  );
247
247
  return null;
248
248
  }
249
+ if (options.break === void 0) {
250
+ if (options.type === "war" || options.type === "log") {
251
+ options.break = false;
252
+ } else {
253
+ options.break = true;
254
+ }
255
+ }
249
256
  return { name, options: { ...options, message } };
250
257
  }
251
- function processEmessage(errorName, config) {
258
+ function processEmessage(errorName, config, errorToThrow) {
252
259
  const message = config.message;
253
260
  let consoleType;
254
261
  if (config.type === false) {
@@ -303,7 +310,7 @@ function processEmessage(errorName, config) {
303
310
  }
304
311
  if (config.break ?? true) {
305
312
  if (isBrowser()) {
306
- throw new Error(message);
313
+ throw errorToThrow || new Error(message);
307
314
  } else {
308
315
  process.exit(1);
309
316
  }
@@ -326,6 +333,7 @@ Emessage.global = function(...configs) {
326
333
  }
327
334
  };
328
335
  function showE(error) {
336
+ const errorForStack = new Error();
329
337
  let config = null;
330
338
  let errorName = null;
331
339
  if (typeof error === "string") {
@@ -349,7 +357,8 @@ function showE(error) {
349
357
  return;
350
358
  }
351
359
  if (config && errorName) {
352
- return processEmessage(errorName, config);
360
+ errorForStack.message = config.message;
361
+ return processEmessage(errorName, config, errorForStack);
353
362
  }
354
363
  }
355
364
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { StoredEmessage } from \"./types\";\r\n\r\nexport const individualMessageStore = new Map<string, StoredEmessage>();\r\nexport const globalMessageStore = new Map<string, StoredEmessage>();\r\n","import { ToastConfig, MessageType } from \"./types\";\r\n\r\nexport function isBrowser(): boolean {\r\n return typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\r\n}\r\n\r\n\r\n/**\r\n * Removes a toast element from the DOM with a fade-out transition.\r\n * @param toastElement The toast element to remove.\r\n */\r\nfunction removeToastElement(toastElement: HTMLElement | null) {\r\n if (!toastElement || !toastElement.parentElement) return;\r\n\r\n toastElement.classList.remove(\"visible\");\r\n // Remove the element after the transition ends to allow for animation\r\n toastElement.addEventListener(\"transitionend\", () => {\r\n const container = toastElement.parentElement;\r\n if (container) {\r\n container.removeChild(toastElement);\r\n // If the container is now empty, remove it from the DOM\r\n if (container.childElementCount === 0 && container.parentElement) {\r\n container.parentElement.removeChild(container);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Initializes the global API for emessages, like window.emessages.closeToast\r\n */\r\nfunction initializeGlobalApi() {\r\n if (!isBrowser()) return;\r\n\r\n // Ensure the global namespace exists\r\n if (!(window as any).emessages) {\r\n (window as any).emessages = {};\r\n }\r\n\r\n // Attach the closeToast function if it doesn't exist\r\n if (!(window as any).emessages.closeToast) {\r\n (window as any).emessages.closeToast = function (eventOrId: Event | string) {\r\n let toastElement: HTMLElement | null = null;\r\n\r\n if (typeof eventOrId === 'string') {\r\n // Find toast by ID\r\n toastElement = document.getElementById(eventOrId);\r\n } else if (eventOrId && eventOrId.target) {\r\n // Find toast by traversing from the event target\r\n toastElement = (eventOrId.target as HTMLElement).closest('.emessage-toast');\r\n }\r\n\r\n if (toastElement) {\r\n removeToastElement(toastElement);\r\n } else {\r\n console.warn('emessages: closeToast() was called but could not find a toast element to close.');\r\n }\r\n };\r\n }\r\n}\r\n\r\n// Initialize the global API when the module is loaded\r\ninitializeGlobalApi();\r\n\r\n\r\n// Function to inject CSS for toasts\r\nfunction injectToastStyles() {\r\n if (!isBrowser()) return;\r\n\r\n const styleId = \"emessages-toast-styles\";\r\n if (document.getElementById(styleId)) {\r\n return; // Styles already injected\r\n }\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = styleId;\r\n style.innerHTML = `\r\n .emessages-toast-container {\r\n position: fixed;\r\n display: flex;\r\n flex-direction: column;\r\n padding: 10px;\r\n pointer-events: none;\r\n z-index: 9999;\r\n box-sizing: border-box;\r\n }\r\n\r\n /* Positioning for containers */\r\n .emessages-toast-container.top-left { top: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.top-center { top: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.top-right { top: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.bottom-left { bottom: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.bottom-center { bottom: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.bottom-right { bottom: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.center { top: 50%; left: 50%; transform: translate(-50%, -50%); align-items: center; }\r\n .emessages-toast-container.center-left { top: 50%; left: 0; transform: translateY(-50%); align-items: flex-start; }\r\n .emessages-toast-container.center-right { top: 50%; right: 0; transform: translateY(-50%); align-items: flex-end; }\r\n\r\n\r\n .emessage-toast {\r\n padding: 12px 18px;\r\n margin: 8px;\r\n border-radius: 6px;\r\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\r\n font-size: 14px;\r\n opacity: 0;\r\n transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;\r\n transform: translateY(20px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n pointer-events: all;\r\n max-width: 350px;\r\n word-break: break-word;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n gap: 10px;\r\n box-sizing: border-box;\r\n }\r\n\r\n .emessage-toast.visible {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n /* Default styles based on message type */\r\n .emessage-toast-err { background-color: #ef4444; color: white; } /* red-500 */\r\n .emessage-toast-war { background-color: #f59e0b; color: white; } /* amber-500 */\r\n .emessage-toast-log { background-color: #ffffff; color: #1f2937; border: 1px solid #e5e7eb; } /* white, gray-800 text, gray-200 border */\r\n\r\n .emessage-toast-message {\r\n flex-grow: 1;\r\n }\r\n\r\n .emessage-toast-close {\r\n background: none;\r\n border: none;\r\n color: inherit;\r\n font-size: 20px;\r\n font-weight: bold;\r\n cursor: pointer;\r\n line-height: 1;\r\n opacity: 0.7;\r\n padding: 0;\r\n margin-left: 15px;\r\n }\r\n .emessage-toast-close:hover {\r\n opacity: 1;\r\n }\r\n .emessage-toast-close:focus,\r\n .emessage-toast-close:focus-visible {\r\n outline: none;\r\n }\r\n `;\r\n // Prepend styles to give user stylesheets higher priority\r\n document.head.insertBefore(style, document.head.firstChild);\r\n}\r\n\r\n// Function to get or create a specific toast container for a position\r\nfunction getOrCreateToastContainer(position: string): HTMLElement {\r\n // Normalize position string to handle variants like \"top\" -> \"top-center\"\r\n const positionMap: Record<string, string> = {\r\n top: \"top-center\",\r\n bottom: \"bottom-center\",\r\n left: \"center-left\",\r\n right: \"center-right\",\r\n center: \"center\",\r\n \"top-right\": \"top-right\",\r\n \"top-left\": \"top-left\",\r\n \"top-center\": \"top-center\",\r\n \"bottom-right\": \"bottom-right\",\r\n \"bottom-left\": \"bottom-left\",\r\n \"bottom-center\": \"bottom-center\",\r\n \"center-left\": \"center-left\",\r\n \"center-right\": \"center-right\",\r\n };\r\n\r\n const normalizedPosition = positionMap[position.toLowerCase().replace(/\\s/g, \"-\")] || \"top-right\";\r\n const containerId = `emessages-toast-container-${normalizedPosition}`;\r\n let container = document.getElementById(containerId);\r\n\r\n if (!container) {\r\n container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.className = `emessages-toast-container ${normalizedPosition}`;\r\n document.body.appendChild(container);\r\n }\r\n return container;\r\n}\r\n\r\n\r\nexport function showToast(\r\n message: string,\r\n toastOptions: boolean | ToastConfig,\r\n messageType: MessageType = \"log\"\r\n): void {\r\n if (!isBrowser()) {\r\n return;\r\n }\r\n\r\n injectToastStyles();\r\n\r\n const config: ToastConfig = typeof toastOptions === \"object\" ? toastOptions : {};\r\n\r\n let {\r\n message: customMessage,\r\n style: customStyle,\r\n class: customClass,\r\n position = \"top-right\",\r\n stay = false,\r\n duration = 3000,\r\n delay = 0,\r\n } = config;\r\n \r\n const toast = document.createElement(\"div\");\r\n // Assign a unique ID for programmatic closing\r\n toast.id = `emessage-toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n \r\n // Base class is applied first\r\n let toastClasses = ['emessage-toast'];\r\n \r\n // Add default type class. We use a separate class to avoid specificity conflicts.\r\n toastClasses.push(`emessage-toast-${messageType}`);\r\n \r\n // Add custom classes. These can now override the default type styles if they have the same specificity.\r\n if (customClass) {\r\n toastClasses.push(...customClass.split(' ').filter(c => c));\r\n }\r\n \r\n toast.className = toastClasses.join(' ');\r\n \r\n // Apply custom inline style from config (highest priority)\r\n if (customStyle) {\r\n toast.style.cssText += customStyle;\r\n }\r\n \r\n // Create a dedicated element for the message to avoid conflicts with the close button\r\n const messageElement = document.createElement('div');\r\n messageElement.className = 'emessage-toast-message';\r\n \r\n // Check if customMessage is a React element or other object, which is invalid.\r\n if (typeof customMessage === 'object' && customMessage !== null) {\r\n console.warn('emessages: The `toast.message` property received an object (likely a React component), but it only accepts an HTML string. Please pass a string of HTML to render it correctly. Falling back to the default message.');\r\n customMessage = undefined; // Use the default message instead\r\n }\r\n \r\n messageElement.innerHTML = customMessage || message;\r\n toast.appendChild(messageElement);\r\n \r\n \r\n // Add close button (always add for accessibility, but control removal logic)\r\n const closeButton = document.createElement(\"button\");\r\n closeButton.className = \"emessage-toast-close\";\r\n closeButton.innerHTML = \"&times;\";\r\n closeButton.setAttribute(\"aria-label\", \"Close\");\r\n closeButton.onclick = () => removeToastElement(toast);\r\n toast.appendChild(closeButton);\r\n \r\n const container = getOrCreateToastContainer(position);\r\n \r\n // Delay the appearance of the toast\r\n setTimeout(() => {\r\n // For bottom-positioned toasts, insert at the top of the container\r\n if (position.includes('bottom')) {\r\n container.prepend(toast);\r\n } else {\r\n container.appendChild(toast);\r\n }\r\n \r\n // Allow the element to be in the DOM before transitioning\r\n requestAnimationFrame(() => {\r\n toast.classList.add(\"visible\");\r\n });\r\n }, delay);\r\n \r\n // Set up auto-hide if not staying\r\n if (!stay) {\r\n const hideTimeout = setTimeout(() => removeToastElement(toast), delay + duration);\r\n // Optional: pause on hover\r\n toast.addEventListener('mouseenter', () => clearTimeout(hideTimeout));\r\n toast.addEventListener('mouseleave', () => {\r\n if (!stay) {\r\n setTimeout(() => removeToastElement(toast), 1000); // Give some time before hiding on mouse leave\r\n }\r\n });\r\n }}\r\n","import { individualMessageStore, globalMessageStore } from \"./store\";\r\nimport type {\r\n EmessageConfig,\r\n EmessageOptions,\r\n StoredEmessage,\r\n ToastConfig,\r\n MessageType,\r\n} from \"./types\";\r\nimport { isBrowser, showToast } from \"./utils\";\r\n\r\nfunction parseConfig(\r\n config: Record<string, any>\r\n): { name: string; options: StoredEmessage } | null {\r\n const options: EmessageOptions = {};\r\n let message: string | null = null;\r\n let name: string | null = null;\r\n const optionKeys = [\"type\", \"break\", \"toast\", \"returnEM\", \"callBack\"];\r\n\r\n for (const key in config) {\r\n if (Object.prototype.hasOwnProperty.call(config, key)) {\r\n if (optionKeys.includes(key)) {\r\n (options as any)[key] = config[key];\r\n } else {\r\n if (name !== null) {\r\n console.warn(\r\n `emessages: Found multiple potential error names in one config object. Using first one found: \"${name}\".`\r\n );\r\n continue;\r\n }\r\n name = key;\r\n message = String(config[key]);\r\n }\r\n }\r\n }\r\n\r\n if (name === null || message === null) {\r\n console.error(\r\n \"emessages: Invalid config object. Could not find error name and message.\",\r\n config\r\n );\r\n return null;\r\n }\r\n\r\n return { name, options: { ...options, message } };\r\n}\r\n\r\nfunction processEmessage(\r\n errorName: string,\r\n config: StoredEmessage\r\n): string | void {\r\n const message = config.message;\r\n\r\n let consoleType: MessageType | false;\r\n if (config.type === false) {\r\n consoleType = false;\r\n } else if (config.type === true || config.type === undefined) {\r\n consoleType = \"err\";\r\n } else {\r\n consoleType = config.type;\r\n }\r\n\r\n // 1. Console log\r\n if (consoleType) {\r\n if (isBrowser()) {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(message);\r\n break;\r\n case \"war\":\r\n console.warn(message);\r\n break;\r\n case \"err\":\r\n console.error(message);\r\n break;\r\n }\r\n } else {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(`\\x1b[30;47m ${message} \\x1b[0m`);\r\n break;\r\n case \"war\":\r\n console.warn(`\\x1b[37;43m ${message} \\x1b[0m`);\r\n break;\r\n case \"err\":\r\n console.error(`\\x1b[37;41m ${message} \\x1b[0m`);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // 2. Toast notification\r\n if (config.toast && isBrowser()) {\r\n showToast(message, config.toast, consoleType as MessageType);\r\n }\r\n\r\n // 3. Callback\r\n if (config.callBack) {\r\n try {\r\n config.callBack();\r\n } catch (e: any) {\r\n console.error(\r\n `emessages: Error in callBack for \"${errorName}\":`,\r\n e.message\r\n );\r\n }\r\n }\r\n\r\n // 4. Return error message\r\n if (config.returnEM) {\r\n return message;\r\n }\r\n\r\n // 5. Break execution\r\n if (config.break ?? true) {\r\n if (isBrowser()) {\r\n throw new Error(message);\r\n } else {\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nexport function Emessage(...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n individualMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n}\r\n\r\nEmessage.global = function (...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n globalMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n};\r\n\r\nexport function showE(error: string | Record<string, any>): string | void {\r\n let config: StoredEmessage | null = null;\r\n let errorName: string | null = null;\r\n\r\n if (typeof error === \"string\") {\r\n errorName = error;\r\n config =\r\n individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;\r\n if (!config) {\r\n console.error(`emessages: Error \"${error}\" not found.`);\r\n return;\r\n }\r\n } else if (typeof error === \"object\" && error !== null) {\r\n const parsed = parseConfig(error);\r\n if (parsed) {\r\n errorName = parsed.name;\r\n config = parsed.options;\r\n } else {\r\n console.error(\"emessages: Invalid object passed to showE.\");\r\n return;\r\n }\r\n } else {\r\n console.error(\"emessages: Invalid argument passed to showE.\");\r\n return;\r\n }\r\n\r\n if (config && errorName) {\r\n return processEmessage(errorName, config);\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/store.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { StoredEmessage } from \"./types\";\r\n\r\nexport const individualMessageStore = new Map<string, StoredEmessage>();\r\nexport const globalMessageStore = new Map<string, StoredEmessage>();\r\n","import { ToastConfig, MessageType } from \"./types\";\r\n\r\nexport function isBrowser(): boolean {\r\n return typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\r\n}\r\n\r\n\r\n/**\r\n * Removes a toast element from the DOM with a fade-out transition.\r\n * @param toastElement The toast element to remove.\r\n */\r\nfunction removeToastElement(toastElement: HTMLElement | null) {\r\n if (!toastElement || !toastElement.parentElement) return;\r\n\r\n toastElement.classList.remove(\"visible\");\r\n // Remove the element after the transition ends to allow for animation\r\n toastElement.addEventListener(\"transitionend\", () => {\r\n const container = toastElement.parentElement;\r\n if (container) {\r\n container.removeChild(toastElement);\r\n // If the container is now empty, remove it from the DOM\r\n if (container.childElementCount === 0 && container.parentElement) {\r\n container.parentElement.removeChild(container);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Initializes the global API for emessages, like window.emessages.closeToast\r\n */\r\nfunction initializeGlobalApi() {\r\n if (!isBrowser()) return;\r\n\r\n // Ensure the global namespace exists\r\n if (!(window as any).emessages) {\r\n (window as any).emessages = {};\r\n }\r\n\r\n // Attach the closeToast function if it doesn't exist\r\n if (!(window as any).emessages.closeToast) {\r\n (window as any).emessages.closeToast = function (eventOrId: Event | string) {\r\n let toastElement: HTMLElement | null = null;\r\n\r\n if (typeof eventOrId === 'string') {\r\n // Find toast by ID\r\n toastElement = document.getElementById(eventOrId);\r\n } else if (eventOrId && eventOrId.target) {\r\n // Find toast by traversing from the event target\r\n toastElement = (eventOrId.target as HTMLElement).closest('.emessage-toast');\r\n }\r\n\r\n if (toastElement) {\r\n removeToastElement(toastElement);\r\n } else {\r\n console.warn('emessages: closeToast() was called but could not find a toast element to close.');\r\n }\r\n };\r\n }\r\n}\r\n\r\n// Initialize the global API when the module is loaded\r\ninitializeGlobalApi();\r\n\r\n\r\n// Function to inject CSS for toasts\r\nfunction injectToastStyles() {\r\n if (!isBrowser()) return;\r\n\r\n const styleId = \"emessages-toast-styles\";\r\n if (document.getElementById(styleId)) {\r\n return; // Styles already injected\r\n }\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = styleId;\r\n style.innerHTML = `\r\n .emessages-toast-container {\r\n position: fixed;\r\n display: flex;\r\n flex-direction: column;\r\n padding: 10px;\r\n pointer-events: none;\r\n z-index: 9999;\r\n box-sizing: border-box;\r\n }\r\n\r\n /* Positioning for containers */\r\n .emessages-toast-container.top-left { top: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.top-center { top: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.top-right { top: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.bottom-left { bottom: 0; left: 0; align-items: flex-start; }\r\n .emessages-toast-container.bottom-center { bottom: 0; left: 50%; transform: translateX(-50%); align-items: center; }\r\n .emessages-toast-container.bottom-right { bottom: 0; right: 0; align-items: flex-end; }\r\n .emessages-toast-container.center { top: 50%; left: 50%; transform: translate(-50%, -50%); align-items: center; }\r\n .emessages-toast-container.center-left { top: 50%; left: 0; transform: translateY(-50%); align-items: flex-start; }\r\n .emessages-toast-container.center-right { top: 50%; right: 0; transform: translateY(-50%); align-items: flex-end; }\r\n\r\n\r\n .emessage-toast {\r\n padding: 12px 18px;\r\n margin: 8px;\r\n border-radius: 6px;\r\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\r\n font-size: 14px;\r\n opacity: 0;\r\n transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;\r\n transform: translateY(20px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n pointer-events: all;\r\n max-width: 350px;\r\n word-break: break-word;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n gap: 10px;\r\n box-sizing: border-box;\r\n }\r\n\r\n .emessage-toast.visible {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n /* Default styles based on message type */\r\n .emessage-toast-err { background-color: #ef4444; color: white; } /* red-500 */\r\n .emessage-toast-war { background-color: #f59e0b; color: white; } /* amber-500 */\r\n .emessage-toast-log { background-color: #ffffff; color: #1f2937; border: 1px solid #e5e7eb; } /* white, gray-800 text, gray-200 border */\r\n\r\n .emessage-toast-message {\r\n flex-grow: 1;\r\n }\r\n\r\n .emessage-toast-close {\r\n background: none;\r\n border: none;\r\n color: inherit;\r\n font-size: 20px;\r\n font-weight: bold;\r\n cursor: pointer;\r\n line-height: 1;\r\n opacity: 0.7;\r\n padding: 0;\r\n margin-left: 15px;\r\n }\r\n .emessage-toast-close:hover {\r\n opacity: 1;\r\n }\r\n .emessage-toast-close:focus,\r\n .emessage-toast-close:focus-visible {\r\n outline: none;\r\n }\r\n `;\r\n // Prepend styles to give user stylesheets higher priority\r\n document.head.insertBefore(style, document.head.firstChild);\r\n}\r\n\r\n// Function to get or create a specific toast container for a position\r\nfunction getOrCreateToastContainer(position: string): HTMLElement {\r\n // Normalize position string to handle variants like \"top\" -> \"top-center\"\r\n const positionMap: Record<string, string> = {\r\n top: \"top-center\",\r\n bottom: \"bottom-center\",\r\n left: \"center-left\",\r\n right: \"center-right\",\r\n center: \"center\",\r\n \"top-right\": \"top-right\",\r\n \"top-left\": \"top-left\",\r\n \"top-center\": \"top-center\",\r\n \"bottom-right\": \"bottom-right\",\r\n \"bottom-left\": \"bottom-left\",\r\n \"bottom-center\": \"bottom-center\",\r\n \"center-left\": \"center-left\",\r\n \"center-right\": \"center-right\",\r\n };\r\n\r\n const normalizedPosition = positionMap[position.toLowerCase().replace(/\\s/g, \"-\")] || \"top-right\";\r\n const containerId = `emessages-toast-container-${normalizedPosition}`;\r\n let container = document.getElementById(containerId);\r\n\r\n if (!container) {\r\n container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.className = `emessages-toast-container ${normalizedPosition}`;\r\n document.body.appendChild(container);\r\n }\r\n return container;\r\n}\r\n\r\n\r\nexport function showToast(\r\n message: string,\r\n toastOptions: boolean | ToastConfig,\r\n messageType: MessageType = \"log\"\r\n): void {\r\n if (!isBrowser()) {\r\n return;\r\n }\r\n\r\n injectToastStyles();\r\n\r\n const config: ToastConfig = typeof toastOptions === \"object\" ? toastOptions : {};\r\n\r\n let {\r\n message: customMessage,\r\n style: customStyle,\r\n class: customClass,\r\n position = \"top-right\",\r\n stay = false,\r\n duration = 3000,\r\n delay = 0,\r\n } = config;\r\n \r\n const toast = document.createElement(\"div\");\r\n // Assign a unique ID for programmatic closing\r\n toast.id = `emessage-toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n \r\n // Base class is applied first\r\n let toastClasses = ['emessage-toast'];\r\n \r\n // Add default type class. We use a separate class to avoid specificity conflicts.\r\n toastClasses.push(`emessage-toast-${messageType}`);\r\n \r\n // Add custom classes. These can now override the default type styles if they have the same specificity.\r\n if (customClass) {\r\n toastClasses.push(...customClass.split(' ').filter(c => c));\r\n }\r\n \r\n toast.className = toastClasses.join(' ');\r\n \r\n // Apply custom inline style from config (highest priority)\r\n if (customStyle) {\r\n toast.style.cssText += customStyle;\r\n }\r\n \r\n // Create a dedicated element for the message to avoid conflicts with the close button\r\n const messageElement = document.createElement('div');\r\n messageElement.className = 'emessage-toast-message';\r\n \r\n // Check if customMessage is a React element or other object, which is invalid.\r\n if (typeof customMessage === 'object' && customMessage !== null) {\r\n console.warn('emessages: The `toast.message` property received an object (likely a React component), but it only accepts an HTML string. Please pass a string of HTML to render it correctly. Falling back to the default message.');\r\n customMessage = undefined; // Use the default message instead\r\n }\r\n \r\n messageElement.innerHTML = customMessage || message;\r\n toast.appendChild(messageElement);\r\n \r\n \r\n // Add close button (always add for accessibility, but control removal logic)\r\n const closeButton = document.createElement(\"button\");\r\n closeButton.className = \"emessage-toast-close\";\r\n closeButton.innerHTML = \"&times;\";\r\n closeButton.setAttribute(\"aria-label\", \"Close\");\r\n closeButton.onclick = () => removeToastElement(toast);\r\n toast.appendChild(closeButton);\r\n \r\n const container = getOrCreateToastContainer(position);\r\n \r\n // Delay the appearance of the toast\r\n setTimeout(() => {\r\n // For bottom-positioned toasts, insert at the top of the container\r\n if (position.includes('bottom')) {\r\n container.prepend(toast);\r\n } else {\r\n container.appendChild(toast);\r\n }\r\n \r\n // Allow the element to be in the DOM before transitioning\r\n requestAnimationFrame(() => {\r\n toast.classList.add(\"visible\");\r\n });\r\n }, delay);\r\n \r\n // Set up auto-hide if not staying\r\n if (!stay) {\r\n const hideTimeout = setTimeout(() => removeToastElement(toast), delay + duration);\r\n // Optional: pause on hover\r\n toast.addEventListener('mouseenter', () => clearTimeout(hideTimeout));\r\n toast.addEventListener('mouseleave', () => {\r\n if (!stay) {\r\n setTimeout(() => removeToastElement(toast), 1000); // Give some time before hiding on mouse leave\r\n }\r\n });\r\n }}\r\n","import { individualMessageStore, globalMessageStore } from \"./store\";\r\nimport type {\r\n EmessageConfig,\r\n EmessageOptions,\r\n StoredEmessage,\r\n ToastConfig,\r\n MessageType,\r\n} from \"./types\";\r\nimport { isBrowser, showToast } from \"./utils\";\r\n\r\nfunction parseConfig(\r\n config: Record<string, any>\r\n): { name: string; options: StoredEmessage } | null {\r\n const options: EmessageOptions = {};\r\n let message: string | null = null;\r\n let name: string | null = null;\r\n const optionKeys = [\"type\", \"break\", \"toast\", \"returnEM\", \"callBack\"];\r\n\r\n for (const key in config) {\r\n if (Object.prototype.hasOwnProperty.call(config, key)) {\r\n if (optionKeys.includes(key)) {\r\n (options as any)[key] = config[key];\r\n } else {\r\n if (name !== null) {\r\n console.warn(\r\n `emessages: Found multiple potential error names in one config object. Using first one found: \"${name}\".`\r\n );\r\n continue;\r\n }\r\n name = key;\r\n message = String(config[key]);\r\n }\r\n }\r\n }\r\n\r\n if (name === null || message === null) {\r\n console.error(\r\n \"emessages: Invalid config object. Could not find error name and message.\",\r\n config\r\n );\r\n return null;\r\n }\r\n\r\n // Apply default for 'break' if not explicitly set\r\n if (options.break === undefined) {\r\n if (options.type === \"war\" || options.type === \"log\") {\r\n options.break = false;\r\n } else {\r\n // Default for 'err' type or if type is not specified\r\n options.break = true;\r\n }\r\n }\r\n\r\n return { name, options: { ...options, message } };\r\n}\r\n\r\nfunction processEmessage(\r\n errorName: string,\r\n config: StoredEmessage,\r\n errorToThrow?: Error\r\n): string | void {\r\n const message = config.message;\r\n\r\n let consoleType: MessageType | false;\r\n if (config.type === false) {\r\n consoleType = false;\r\n } else if (config.type === true || config.type === undefined) {\r\n consoleType = \"err\";\r\n } else {\r\n consoleType = config.type;\r\n }\r\n\r\n // 1. Console log\r\n if (consoleType) {\r\n if (isBrowser()) {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(message);\r\n break;\r\n case \"war\":\r\n console.warn(message);\r\n break;\r\n case \"err\":\r\n console.error(message);\r\n break;\r\n }\r\n } else {\r\n switch (consoleType) {\r\n case \"log\":\r\n console.log(`\\x1b[30;47m ${message} \\x1b[0m`);\r\n break;\r\n case \"war\":\r\n console.warn(`\\x1b[37;43m ${message} \\x1b[0m`);\r\n break;\r\n case \"err\":\r\n console.error(`\\x1b[37;41m ${message} \\x1b[0m`);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // 2. Toast notification\r\n if (config.toast && isBrowser()) {\r\n showToast(message, config.toast, consoleType as MessageType);\r\n }\r\n\r\n // 3. Callback\r\n if (config.callBack) {\r\n try {\r\n config.callBack();\r\n } catch (e: any) {\r\n console.error(\r\n `emessages: Error in callBack for \"${errorName}\":`,\r\n e.message\r\n );\r\n }\r\n }\r\n\r\n // 4. Return error message\r\n if (config.returnEM) {\r\n return message;\r\n }\r\n\r\n // 5. Break execution\r\n if (config.break ?? true) {\r\n if (isBrowser()) {\r\n throw errorToThrow || new Error(message);\r\n } else {\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nexport function Emessage(...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n individualMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n}\r\n\r\nEmessage.global = function (...configs: EmessageConfig[]) {\r\n for (const config of configs) {\r\n const parsed = parseConfig(config);\r\n if (parsed) {\r\n globalMessageStore.set(parsed.name, parsed.options);\r\n }\r\n }\r\n};\r\n\r\nexport function showE(error: string | Record<string, any>): string | void {\r\n const errorForStack = new Error();\r\n let config: StoredEmessage | null = null;\r\n let errorName: string | null = null;\r\n\r\n if (typeof error === \"string\") {\r\n errorName = error;\r\n config =\r\n individualMessageStore.get(error) ?? globalMessageStore.get(error) ?? null;\r\n if (!config) {\r\n console.error(`emessages: Error \"${error}\" not found.`);\r\n return;\r\n }\r\n } else if (typeof error === \"object\" && error !== null) {\r\n const parsed = parseConfig(error);\r\n if (parsed) {\r\n errorName = parsed.name;\r\n config = parsed.options;\r\n } else {\r\n console.error(\"emessages: Invalid object passed to showE.\");\r\n return;\r\n }\r\n } else {\r\n console.error(\"emessages: Invalid argument passed to showE.\");\r\n return;\r\n }\r\n\r\n if (config && errorName) {\r\n errorForStack.message = config.message;\r\n return processEmessage(errorName, config, errorForStack);\r\n }\r\n}\r\n"],"mappings":";AAEO,IAAM,yBAAyB,oBAAI,IAA4B;AAC/D,IAAM,qBAAqB,oBAAI,IAA4B;;;ACD3D,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW,eAAe,OAAO,OAAO,aAAa;AACrE;AAOA,SAAS,mBAAmB,cAAkC;AAC5D,MAAI,CAAC,gBAAgB,CAAC,aAAa,cAAe;AAElD,eAAa,UAAU,OAAO,SAAS;AAEvC,eAAa,iBAAiB,iBAAiB,MAAM;AACnD,UAAM,YAAY,aAAa;AAC/B,QAAI,WAAW;AACb,gBAAU,YAAY,YAAY;AAElC,UAAI,UAAU,sBAAsB,KAAK,UAAU,eAAe;AAChE,kBAAU,cAAc,YAAY,SAAS;AAAA,MAC/C;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKA,SAAS,sBAAsB;AAC7B,MAAI,CAAC,UAAU,EAAG;AAGlB,MAAI,CAAE,OAAe,WAAW;AAC9B,IAAC,OAAe,YAAY,CAAC;AAAA,EAC/B;AAGA,MAAI,CAAE,OAAe,UAAU,YAAY;AACzC,IAAC,OAAe,UAAU,aAAa,SAAU,WAA2B;AAC1E,UAAI,eAAmC;AAEvC,UAAI,OAAO,cAAc,UAAU;AAEjC,uBAAe,SAAS,eAAe,SAAS;AAAA,MAClD,WAAW,aAAa,UAAU,QAAQ;AAExC,uBAAgB,UAAU,OAAuB,QAAQ,iBAAiB;AAAA,MAC5E;AAEA,UAAI,cAAc;AAChB,2BAAmB,YAAY;AAAA,MACjC,OAAO;AACL,gBAAQ,KAAK,iFAAiF;AAAA,MAChG;AAAA,IACF;AAAA,EACF;AACF;AAGA,oBAAoB;AAIpB,SAAS,oBAAoB;AAC3B,MAAI,CAAC,UAAU,EAAG;AAElB,QAAM,UAAU;AAChB,MAAI,SAAS,eAAe,OAAO,GAAG;AACpC;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,KAAK;AACX,QAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8ElB,WAAS,KAAK,aAAa,OAAO,SAAS,KAAK,UAAU;AAC5D;AAGA,SAAS,0BAA0B,UAA+B;AAEhE,QAAM,cAAsC;AAAA,IAC1C,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AAEA,QAAM,qBAAqB,YAAY,SAAS,YAAY,EAAE,QAAQ,OAAO,GAAG,CAAC,KAAK;AACtF,QAAM,cAAc,6BAA6B,kBAAkB;AACnE,MAAI,YAAY,SAAS,eAAe,WAAW;AAEnD,MAAI,CAAC,WAAW;AACd,gBAAY,SAAS,cAAc,KAAK;AACxC,cAAU,KAAK;AACf,cAAU,YAAY,6BAA6B,kBAAkB;AACrE,aAAS,KAAK,YAAY,SAAS;AAAA,EACrC;AACA,SAAO;AACT;AAGO,SAAS,UACd,SACA,cACA,cAA2B,OACrB;AACN,MAAI,CAAC,UAAU,GAAG;AAChB;AAAA,EACF;AAEA,oBAAkB;AAElB,QAAM,SAAsB,OAAO,iBAAiB,WAAW,eAAe,CAAC;AAE7E,MAAI;AAAA,IACF,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ;AAAA,EACV,IAAI;AAEJ,QAAM,QAAQ,SAAS,cAAc,KAAK;AAE1C,QAAM,KAAK,kBAAkB,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AAGlF,MAAI,eAAe,CAAC,gBAAgB;AAGpC,eAAa,KAAK,kBAAkB,WAAW,EAAE;AAGjD,MAAI,aAAa;AACf,iBAAa,KAAK,GAAG,YAAY,MAAM,GAAG,EAAE,OAAO,OAAK,CAAC,CAAC;AAAA,EAC5D;AAEA,QAAM,YAAY,aAAa,KAAK,GAAG;AAGvC,MAAI,aAAa;AACf,UAAM,MAAM,WAAW;AAAA,EACzB;AAGA,QAAM,iBAAiB,SAAS,cAAc,KAAK;AACnD,iBAAe,YAAY;AAG3B,MAAI,OAAO,kBAAkB,YAAY,kBAAkB,MAAM;AAC7D,YAAQ,KAAK,sNAAsN;AACnO,oBAAgB;AAAA,EACpB;AAEA,iBAAe,YAAY,iBAAiB;AAC5C,QAAM,YAAY,cAAc;AAIhC,QAAM,cAAc,SAAS,cAAc,QAAQ;AACnD,cAAY,YAAY;AACxB,cAAY,YAAY;AACxB,cAAY,aAAa,cAAc,OAAO;AAC9C,cAAY,UAAU,MAAM,mBAAmB,KAAK;AACpD,QAAM,YAAY,WAAW;AAE7B,QAAM,YAAY,0BAA0B,QAAQ;AAGpD,aAAW,MAAM;AAEf,QAAI,SAAS,SAAS,QAAQ,GAAG;AAC7B,gBAAU,QAAQ,KAAK;AAAA,IAC3B,OAAO;AACH,gBAAU,YAAY,KAAK;AAAA,IAC/B;AAGA,0BAAsB,MAAM;AACxB,YAAM,UAAU,IAAI,SAAS;AAAA,IACjC,CAAC;AAAA,EACH,GAAG,KAAK;AAGR,MAAI,CAAC,MAAM;AACT,UAAM,cAAc,WAAW,MAAM,mBAAmB,KAAK,GAAG,QAAQ,QAAQ;AAEhF,UAAM,iBAAiB,cAAc,MAAM,aAAa,WAAW,CAAC;AACpE,UAAM,iBAAiB,cAAc,MAAM;AACvC,UAAI,CAAC,MAAM;AACP,mBAAW,MAAM,mBAAmB,KAAK,GAAG,GAAI;AAAA,MACpD;AAAA,IACJ,CAAC;AAAA,EACH;AAAC;;;AClRL,SAAS,YACP,QACkD;AAClD,QAAM,UAA2B,CAAC;AAClC,MAAI,UAAyB;AAC7B,MAAI,OAAsB;AAC1B,QAAM,aAAa,CAAC,QAAQ,SAAS,SAAS,YAAY,UAAU;AAEpE,aAAW,OAAO,QAAQ;AACxB,QAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,GAAG;AACrD,UAAI,WAAW,SAAS,GAAG,GAAG;AAC5B,QAAC,QAAgB,GAAG,IAAI,OAAO,GAAG;AAAA,MACpC,OAAO;AACL,YAAI,SAAS,MAAM;AACjB,kBAAQ;AAAA,YACN,iGAAiG,IAAI;AAAA,UACvG;AACA;AAAA,QACF;AACA,eAAO;AACP,kBAAU,OAAO,OAAO,GAAG,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ,YAAY,MAAM;AACrC,YAAQ;AAAA,MACN;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,UAAU,QAAW;AAC/B,QAAI,QAAQ,SAAS,SAAS,QAAQ,SAAS,OAAO;AACpD,cAAQ,QAAQ;AAAA,IAClB,OAAO;AAEL,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,EAAE,GAAG,SAAS,QAAQ,EAAE;AAClD;AAEA,SAAS,gBACP,WACA,QACA,cACe;AACf,QAAM,UAAU,OAAO;AAEvB,MAAI;AACJ,MAAI,OAAO,SAAS,OAAO;AACzB,kBAAc;AAAA,EAChB,WAAW,OAAO,SAAS,QAAQ,OAAO,SAAS,QAAW;AAC5D,kBAAc;AAAA,EAChB,OAAO;AACL,kBAAc,OAAO;AAAA,EACvB;AAGA,MAAI,aAAa;AACf,QAAI,UAAU,GAAG;AACf,cAAQ,aAAa;AAAA,QACnB,KAAK;AACH,kBAAQ,IAAI,OAAO;AACnB;AAAA,QACF,KAAK;AACH,kBAAQ,KAAK,OAAO;AACpB;AAAA,QACF,KAAK;AACH,kBAAQ,MAAM,OAAO;AACrB;AAAA,MACJ;AAAA,IACF,OAAO;AACL,cAAQ,aAAa;AAAA,QACnB,KAAK;AACH,kBAAQ,IAAI,eAAe,OAAO,UAAU;AAC5C;AAAA,QACF,KAAK;AACH,kBAAQ,KAAK,eAAe,OAAO,UAAU;AAC7C;AAAA,QACF,KAAK;AACH,kBAAQ,MAAM,eAAe,OAAO,UAAU;AAC9C;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,UAAU,GAAG;AAC/B,cAAU,SAAS,OAAO,OAAO,WAA0B;AAAA,EAC7D;AAGA,MAAI,OAAO,UAAU;AACnB,QAAI;AACF,aAAO,SAAS;AAAA,IAClB,SAAS,GAAQ;AACf,cAAQ;AAAA,QACN,qCAAqC,SAAS;AAAA,QAC9C,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,UAAU;AACnB,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,SAAS,MAAM;AACxB,QAAI,UAAU,GAAG;AACf,YAAM,gBAAgB,IAAI,MAAM,OAAO;AAAA,IACzC,OAAO;AACL,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AAEO,SAAS,YAAY,SAA2B;AACrD,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,YAAY,MAAM;AACjC,QAAI,QAAQ;AACV,6BAAuB,IAAI,OAAO,MAAM,OAAO,OAAO;AAAA,IACxD;AAAA,EACF;AACF;AAEA,SAAS,SAAS,YAAa,SAA2B;AACxD,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,YAAY,MAAM;AACjC,QAAI,QAAQ;AACV,yBAAmB,IAAI,OAAO,MAAM,OAAO,OAAO;AAAA,IACpD;AAAA,EACF;AACF;AAEO,SAAS,MAAM,OAAoD;AACxE,QAAM,gBAAgB,IAAI,MAAM;AAChC,MAAI,SAAgC;AACpC,MAAI,YAA2B;AAE/B,MAAI,OAAO,UAAU,UAAU;AAC7B,gBAAY;AACZ,aACE,uBAAuB,IAAI,KAAK,KAAK,mBAAmB,IAAI,KAAK,KAAK;AACxE,QAAI,CAAC,QAAQ;AACX,cAAQ,MAAM,qBAAqB,KAAK,cAAc;AACtD;AAAA,IACF;AAAA,EACF,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACtD,UAAM,SAAS,YAAY,KAAK;AAChC,QAAI,QAAQ;AACV,kBAAY,OAAO;AACnB,eAAS,OAAO;AAAA,IAClB,OAAO;AACL,cAAQ,MAAM,4CAA4C;AAC1D;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,MAAM,8CAA8C;AAC5D;AAAA,EACF;AAEA,MAAI,UAAU,WAAW;AACvB,kBAAc,UAAU,OAAO;AAC/B,WAAO,gBAAgB,WAAW,QAAQ,aAAa;AAAA,EACzD;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emessages",
3
- "version": "2.2.0",
3
+ "version": "2.2.4",
4
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
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -29,6 +29,9 @@
29
29
  "scripts": {
30
30
  "build": "tsup"
31
31
  },
32
+ "bin": {
33
+ "emessages": "./dist/cli.cjs"
34
+ },
32
35
  "devDependencies": {
33
36
  "@types/node": "^20.11.24",
34
37
  "tsup": "^8.0.2",