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 +101 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +78 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.cjs +12 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +12 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
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
|
package/dist/cli.cjs.map
ADDED
|
@@ -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
|
package/dist/cli.mjs.map
ADDED
|
@@ -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
|
-
|
|
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:
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 = \"×\";\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 = \"×\";\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":[]}
|
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
|
-
|
|
360
|
+
errorForStack.message = config.message;
|
|
361
|
+
return processEmessage(errorName, config, errorForStack);
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -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 = \"×\";\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 = \"×\";\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":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emessages",
|
|
3
|
-
"version": "2.2.
|
|
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",
|