emoji-space-shim 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/LICENSE +21 -0
  2. package/dist/contract/sdk/shimConsoleLog.d.ts +10 -0
  3. package/dist/contract/sdk/shimConsoleLog.js +28 -0
  4. package/dist/contract/sdk/shimConsoleLog.js.map +1 -0
  5. package/dist/contract/sdk/withEmojiSpaceShim.d.ts +7 -0
  6. package/dist/contract/sdk/withEmojiSpaceShim.js +22 -0
  7. package/dist/contract/sdk/withEmojiSpaceShim.js.map +1 -0
  8. package/dist/domain.objects/EmojiSpaceRegistry.d.ts +6 -0
  9. package/dist/domain.objects/EmojiSpaceRegistry.js +16 -0
  10. package/dist/domain.objects/EmojiSpaceRegistry.js.map +1 -0
  11. package/dist/domain.objects/TerminalChoice.d.ts +5 -0
  12. package/dist/domain.objects/TerminalChoice.js +3 -0
  13. package/dist/domain.objects/TerminalChoice.js.map +1 -0
  14. package/dist/domain.operations/computeSpaceAdjustment.d.ts +11 -0
  15. package/dist/domain.operations/computeSpaceAdjustment.js +15 -0
  16. package/dist/domain.operations/computeSpaceAdjustment.js.map +1 -0
  17. package/dist/domain.operations/detectTerminalChoice.d.ts +6 -0
  18. package/dist/domain.operations/detectTerminalChoice.js +21 -0
  19. package/dist/domain.operations/detectTerminalChoice.js.map +1 -0
  20. package/dist/domain.operations/transformConsoleArgs.d.ts +9 -0
  21. package/dist/domain.operations/transformConsoleArgs.js +23 -0
  22. package/dist/domain.operations/transformConsoleArgs.js.map +1 -0
  23. package/dist/domain.operations/transformMessageForTerminal.d.ts +11 -0
  24. package/dist/domain.operations/transformMessageForTerminal.js +30 -0
  25. package/dist/domain.operations/transformMessageForTerminal.js.map +1 -0
  26. package/dist/index.d.ts +12 -0
  27. package/dist/index.js +24 -0
  28. package/dist/index.js.map +1 -0
  29. package/license.md +21 -0
  30. package/package.json +105 -0
  31. package/readme.md +110 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Uladzimir Kasacheuski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ import type { TerminalChoice } from '../../domain.objects/TerminalChoice';
2
+ /**
3
+ * .what = apply the console.log shim for emoji space adjustment
4
+ * .why = enables automatic emoji space fix across different terminals
5
+ */
6
+ export declare const shimConsoleLog: (input?: {
7
+ terminal?: TerminalChoice;
8
+ }) => {
9
+ restore: () => void;
10
+ };
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shimConsoleLog = void 0;
4
+ const detectTerminalChoice_1 = require("../../domain.operations/detectTerminalChoice");
5
+ const transformConsoleArgs_1 = require("../../domain.operations/transformConsoleArgs");
6
+ /**
7
+ * .what = apply the console.log shim for emoji space adjustment
8
+ * .why = enables automatic emoji space fix across different terminals
9
+ */
10
+ const shimConsoleLog = (input) => {
11
+ // detect or use provided terminal
12
+ const terminal = input?.terminal ?? (0, detectTerminalChoice_1.detectTerminalChoice)();
13
+ // store original console.log
14
+ const originalLog = console.log;
15
+ // replace console.log with transform wrapper
16
+ console.log = (...args) => {
17
+ const transformed = (0, transformConsoleArgs_1.transformConsoleArgs)({ args, terminal });
18
+ originalLog.apply(console, transformed);
19
+ };
20
+ // return restore function
21
+ return {
22
+ restore: () => {
23
+ console.log = originalLog;
24
+ },
25
+ };
26
+ };
27
+ exports.shimConsoleLog = shimConsoleLog;
28
+ //# sourceMappingURL=shimConsoleLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shimConsoleLog.js","sourceRoot":"","sources":["../../../src/contract/sdk/shimConsoleLog.ts"],"names":[],"mappings":";;;AACA,sFAAmF;AACnF,sFAAmF;AAEnF;;;GAGG;AACI,MAAM,cAAc,GAAG,CAAC,KAE9B,EAA2B,EAAE;IAC5B,kCAAkC;IAClC,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,IAAI,IAAA,2CAAoB,GAAE,CAAC;IAE3D,6BAA6B;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAEhC,6CAA6C;IAC7C,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;QACnC,MAAM,WAAW,GAAG,IAAA,2CAAoB,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7D,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,0BAA0B;IAC1B,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO,CAAC,GAAG,GAAG,WAAW,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AArBW,QAAA,cAAc,kBAqBzB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * .what = wrapper that applies emoji space shim for duration of logic execution
3
+ * .why = abstracts shim lifecycle; guarantees restore via finally block
4
+ */
5
+ export declare const withEmojiSpaceShim: <T>(input: {
6
+ logic: () => Promise<T>;
7
+ }) => Promise<T>;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withEmojiSpaceShim = void 0;
4
+ const shimConsoleLog_1 = require("./shimConsoleLog");
5
+ /**
6
+ * .what = wrapper that applies emoji space shim for duration of logic execution
7
+ * .why = abstracts shim lifecycle; guarantees restore via finally block
8
+ */
9
+ const withEmojiSpaceShim = async (input) => {
10
+ // apply the shim before logic executes
11
+ const shim = (0, shimConsoleLog_1.shimConsoleLog)();
12
+ try {
13
+ // execute the wrapped logic
14
+ return await input.logic();
15
+ }
16
+ finally {
17
+ // restore original console.log (runs on normal exit, error exit, or signal)
18
+ shim.restore();
19
+ }
20
+ };
21
+ exports.withEmojiSpaceShim = withEmojiSpaceShim;
22
+ //# sourceMappingURL=withEmojiSpaceShim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withEmojiSpaceShim.js","sourceRoot":"","sources":["../../../src/contract/sdk/withEmojiSpaceShim.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAElD;;;GAGG;AACI,MAAM,kBAAkB,GAAG,KAAK,EAAK,KAE3C,EAAc,EAAE;IACf,uCAAuC;IACvC,MAAM,IAAI,GAAG,IAAA,+BAAc,GAAE,CAAC;IAE9B,IAAI,CAAC;QACH,4BAA4B;QAC5B,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;YAAS,CAAC;QACT,4EAA4E;QAC5E,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;AACH,CAAC,CAAC;AAbW,QAAA,kBAAkB,sBAa7B"}
@@ -0,0 +1,6 @@
1
+ import type { TerminalChoice } from './TerminalChoice';
2
+ /**
3
+ * .what = dictionary of emoji space consumption per terminal
4
+ * .why = terminals disagree on emoji width; this maps emoji → terminal → consumed spaces
5
+ */
6
+ export declare const EMOJI_SPACE_REGISTRY: Record<string, Partial<Record<TerminalChoice, number>>>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EMOJI_SPACE_REGISTRY = void 0;
4
+ /**
5
+ * .what = dictionary of emoji space consumption per terminal
6
+ * .why = terminals disagree on emoji width; this maps emoji → terminal → consumed spaces
7
+ */
8
+ exports.EMOJI_SPACE_REGISTRY = {
9
+ // emojis that consume 1 extra space in vscode only
10
+ '🦫': { vscode: 1, default: 0 },
11
+ '🪨': { vscode: 1, default: 0 },
12
+ // emojis that consume 1 extra space in both vscode and standard terminals
13
+ '🌩️': { vscode: 1, default: 1 },
14
+ '⛈️': { vscode: 1, default: 1 },
15
+ };
16
+ //# sourceMappingURL=EmojiSpaceRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmojiSpaceRegistry.js","sourceRoot":"","sources":["../../src/domain.objects/EmojiSpaceRegistry.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACU,QAAA,oBAAoB,GAG7B;IACF,mDAAmD;IACnD,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;IAC/B,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;IAE/B,0EAA0E;IAC1E,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;IAChC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;CAChC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * .what = terminal type enum for space adjustment rules
3
+ * .why = different terminals render emoji widths differently
4
+ */
5
+ export type TerminalChoice = 'vscode' | 'xterm' | 'gnome' | 'default';
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=TerminalChoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TerminalChoice.js","sourceRoot":"","sources":["../../src/domain.objects/TerminalChoice.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { EMOJI_SPACE_REGISTRY } from '../domain.objects/EmojiSpaceRegistry';
2
+ import type { TerminalChoice } from '../domain.objects/TerminalChoice';
3
+ /**
4
+ * .what = compute how many spaces to add after an emoji for correct render
5
+ * .why = different terminals consume different space widths for emojis
6
+ */
7
+ export declare const computeSpaceAdjustment: (input: {
8
+ emoji: string;
9
+ terminal: TerminalChoice;
10
+ registry?: typeof EMOJI_SPACE_REGISTRY;
11
+ }) => number;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeSpaceAdjustment = void 0;
4
+ const EmojiSpaceRegistry_1 = require("../domain.objects/EmojiSpaceRegistry");
5
+ /**
6
+ * .what = compute how many spaces to add after an emoji for correct render
7
+ * .why = different terminals consume different space widths for emojis
8
+ */
9
+ const computeSpaceAdjustment = (input) => {
10
+ const rules = input.registry ?? EmojiSpaceRegistry_1.EMOJI_SPACE_REGISTRY;
11
+ // lookup terminal-specific rule, fallback to default, fallback to 0
12
+ return (rules[input.emoji]?.[input.terminal] ?? rules[input.emoji]?.default ?? 0);
13
+ };
14
+ exports.computeSpaceAdjustment = computeSpaceAdjustment;
15
+ //# sourceMappingURL=computeSpaceAdjustment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeSpaceAdjustment.js","sourceRoot":"","sources":["../../src/domain.operations/computeSpaceAdjustment.ts"],"names":[],"mappings":";;;AAAA,+EAA8E;AAG9E;;;GAGG;AACI,MAAM,sBAAsB,GAAG,CAAC,KAItC,EAAU,EAAE;IACX,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,IAAI,yCAAoB,CAAC;IAErD,oEAAoE;IACpE,OAAO,CACL,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,IAAI,CAAC,CACzE,CAAC;AACJ,CAAC,CAAC;AAXW,QAAA,sBAAsB,0BAWjC"}
@@ -0,0 +1,6 @@
1
+ import type { TerminalChoice } from '../domain.objects/TerminalChoice';
2
+ /**
3
+ * .what = detect the current terminal type from environment
4
+ * .why = enables auto-detection for space adjustment rules
5
+ */
6
+ export declare const detectTerminalChoice: () => TerminalChoice;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectTerminalChoice = void 0;
4
+ /**
5
+ * .what = detect the current terminal type from environment
6
+ * .why = enables auto-detection for space adjustment rules
7
+ */
8
+ const detectTerminalChoice = () => {
9
+ // check TERM_PROGRAM first (most specific)
10
+ if (process.env.TERM_PROGRAM === 'vscode')
11
+ return 'vscode';
12
+ if (process.env.TERM_PROGRAM === 'gnome-terminal')
13
+ return 'gnome';
14
+ // check TERM for xterm variants
15
+ if (process.env.TERM?.includes('xterm'))
16
+ return 'xterm';
17
+ // fallback to default
18
+ return 'default';
19
+ };
20
+ exports.detectTerminalChoice = detectTerminalChoice;
21
+ //# sourceMappingURL=detectTerminalChoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectTerminalChoice.js","sourceRoot":"","sources":["../../src/domain.operations/detectTerminalChoice.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACI,MAAM,oBAAoB,GAAG,GAAmB,EAAE;IACvD,2CAA2C;IAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC3D,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,gBAAgB;QAAE,OAAO,OAAO,CAAC;IAElE,gCAAgC;IAChC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAExD,sBAAsB;IACtB,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAVW,QAAA,oBAAoB,wBAU/B"}
@@ -0,0 +1,9 @@
1
+ import type { TerminalChoice } from '../domain.objects/TerminalChoice';
2
+ /**
3
+ * .what = transform console.log arguments for emoji space adjustment
4
+ * .why = handles mixed argument types (strings, objects, etc)
5
+ */
6
+ export declare const transformConsoleArgs: (input: {
7
+ args: unknown[];
8
+ terminal: TerminalChoice;
9
+ }) => unknown[];
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformConsoleArgs = void 0;
4
+ const transformMessageForTerminal_1 = require("./transformMessageForTerminal");
5
+ /**
6
+ * .what = transform console.log arguments for emoji space adjustment
7
+ * .why = handles mixed argument types (strings, objects, etc)
8
+ */
9
+ const transformConsoleArgs = (input) => {
10
+ return input.args.map((arg) => {
11
+ // only transform string arguments
12
+ if (typeof arg === 'string') {
13
+ return (0, transformMessageForTerminal_1.transformMessageForTerminal)({
14
+ message: arg,
15
+ terminal: input.terminal,
16
+ });
17
+ }
18
+ // pass through non-strings unchanged
19
+ return arg;
20
+ });
21
+ };
22
+ exports.transformConsoleArgs = transformConsoleArgs;
23
+ //# sourceMappingURL=transformConsoleArgs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformConsoleArgs.js","sourceRoot":"","sources":["../../src/domain.operations/transformConsoleArgs.ts"],"names":[],"mappings":";;;AAEA,+EAA4E;AAE5E;;;GAGG;AACI,MAAM,oBAAoB,GAAG,CAAC,KAGpC,EAAa,EAAE;IACd,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC5B,kCAAkC;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,IAAA,yDAA2B,EAAC;gBACjC,OAAO,EAAE,GAAG;gBACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;QACL,CAAC;QAED,qCAAqC;QACrC,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAhBW,QAAA,oBAAoB,wBAgB/B"}
@@ -0,0 +1,11 @@
1
+ import { EMOJI_SPACE_REGISTRY } from '../domain.objects/EmojiSpaceRegistry';
2
+ import type { TerminalChoice } from '../domain.objects/TerminalChoice';
3
+ /**
4
+ * .what = transform a message by add spaces after registered emojis
5
+ * .why = adjusts emoji space consumption for correct terminal render
6
+ */
7
+ export declare const transformMessageForTerminal: (input: {
8
+ message: string;
9
+ terminal: TerminalChoice;
10
+ registry?: typeof EMOJI_SPACE_REGISTRY;
11
+ }) => string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformMessageForTerminal = void 0;
4
+ const EmojiSpaceRegistry_1 = require("../domain.objects/EmojiSpaceRegistry");
5
+ const computeSpaceAdjustment_1 = require("./computeSpaceAdjustment");
6
+ /**
7
+ * .what = transform a message by add spaces after registered emojis
8
+ * .why = adjusts emoji space consumption for correct terminal render
9
+ */
10
+ const transformMessageForTerminal = (input) => {
11
+ const registry = input.registry ?? EmojiSpaceRegistry_1.EMOJI_SPACE_REGISTRY;
12
+ let result = input.message;
13
+ // iterate through registered emojis and add spaces where needed
14
+ for (const emoji of Object.keys(registry)) {
15
+ const adjustment = (0, computeSpaceAdjustment_1.computeSpaceAdjustment)({
16
+ emoji,
17
+ terminal: input.terminal,
18
+ registry,
19
+ });
20
+ // skip if no adjustment needed
21
+ if (adjustment === 0)
22
+ continue;
23
+ // insert spaces after each occurrence of the emoji
24
+ const spaces = ' '.repeat(adjustment);
25
+ result = result.split(emoji).join(emoji + spaces);
26
+ }
27
+ return result;
28
+ };
29
+ exports.transformMessageForTerminal = transformMessageForTerminal;
30
+ //# sourceMappingURL=transformMessageForTerminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformMessageForTerminal.js","sourceRoot":"","sources":["../../src/domain.operations/transformMessageForTerminal.ts"],"names":[],"mappings":";;;AAAA,+EAA8E;AAG9E,qEAAkE;AAElE;;;GAGG;AACI,MAAM,2BAA2B,GAAG,CAAC,KAI3C,EAAU,EAAE;IACX,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,yCAAoB,CAAC;IACxD,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;IAE3B,gEAAgE;IAChE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAA,+CAAsB,EAAC;YACxC,KAAK;YACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ;SACT,CAAC,CAAC;QAEH,+BAA+B;QAC/B,IAAI,UAAU,KAAK,CAAC;YAAE,SAAS;QAE/B,mDAAmD;QACnD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAzBW,QAAA,2BAA2B,+BAyBtC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * emoji-space-shim
3
+ *
4
+ * shim console.log to fix emoji space render issues across terminals.
5
+ */
6
+ export { shimConsoleLog } from './contract/sdk/shimConsoleLog';
7
+ export { withEmojiSpaceShim } from './contract/sdk/withEmojiSpaceShim';
8
+ export { EMOJI_SPACE_REGISTRY } from './domain.objects/EmojiSpaceRegistry';
9
+ export type { TerminalChoice } from './domain.objects/TerminalChoice';
10
+ export { computeSpaceAdjustment } from './domain.operations/computeSpaceAdjustment';
11
+ export { detectTerminalChoice } from './domain.operations/detectTerminalChoice';
12
+ export { transformMessageForTerminal } from './domain.operations/transformMessageForTerminal';
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * emoji-space-shim
4
+ *
5
+ * shim console.log to fix emoji space render issues across terminals.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.transformMessageForTerminal = exports.detectTerminalChoice = exports.computeSpaceAdjustment = exports.EMOJI_SPACE_REGISTRY = exports.withEmojiSpaceShim = exports.shimConsoleLog = void 0;
9
+ // main shim
10
+ var shimConsoleLog_1 = require("./contract/sdk/shimConsoleLog");
11
+ Object.defineProperty(exports, "shimConsoleLog", { enumerable: true, get: function () { return shimConsoleLog_1.shimConsoleLog; } });
12
+ var withEmojiSpaceShim_1 = require("./contract/sdk/withEmojiSpaceShim");
13
+ Object.defineProperty(exports, "withEmojiSpaceShim", { enumerable: true, get: function () { return withEmojiSpaceShim_1.withEmojiSpaceShim; } });
14
+ // registry (for extension by consumers)
15
+ var EmojiSpaceRegistry_1 = require("./domain.objects/EmojiSpaceRegistry");
16
+ Object.defineProperty(exports, "EMOJI_SPACE_REGISTRY", { enumerable: true, get: function () { return EmojiSpaceRegistry_1.EMOJI_SPACE_REGISTRY; } });
17
+ var computeSpaceAdjustment_1 = require("./domain.operations/computeSpaceAdjustment");
18
+ Object.defineProperty(exports, "computeSpaceAdjustment", { enumerable: true, get: function () { return computeSpaceAdjustment_1.computeSpaceAdjustment; } });
19
+ // operations (for advanced use cases)
20
+ var detectTerminalChoice_1 = require("./domain.operations/detectTerminalChoice");
21
+ Object.defineProperty(exports, "detectTerminalChoice", { enumerable: true, get: function () { return detectTerminalChoice_1.detectTerminalChoice; } });
22
+ var transformMessageForTerminal_1 = require("./domain.operations/transformMessageForTerminal");
23
+ Object.defineProperty(exports, "transformMessageForTerminal", { enumerable: true, get: function () { return transformMessageForTerminal_1.transformMessageForTerminal; } });
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,YAAY;AACZ,gEAA+D;AAAtD,gHAAA,cAAc,OAAA;AACvB,wEAAuE;AAA9D,wHAAA,kBAAkB,OAAA;AAC3B,wCAAwC;AACxC,0EAA2E;AAAlE,0HAAA,oBAAoB,OAAA;AAG7B,qFAAoF;AAA3E,gIAAA,sBAAsB,OAAA;AAC/B,sCAAsC;AACtC,iFAAgF;AAAvE,4HAAA,oBAAoB,OAAA;AAC7B,+FAA8F;AAArF,0IAAA,2BAA2B,OAAA"}
package/license.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 ehmpathy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "emoji-space-shim",
3
+ "author": "ehmpathy",
4
+ "description": "shim console.log to fix emoji space render issues across terminals",
5
+ "version": "0.0.0",
6
+ "repository": "ehmpathy/emoji-space-shim",
7
+ "homepage": "https://github.com/ehmpathy/emoji-space-shim",
8
+ "keywords": [
9
+ "emoji",
10
+ "terminal",
11
+ "console",
12
+ "shim",
13
+ "vscode",
14
+ "xterm",
15
+ "unicode",
16
+ "character-width"
17
+ ],
18
+ "bugs": "https://github.com/ehmpathy/emoji-space-shim/issues",
19
+ "license": "MIT",
20
+ "main": "dist/index.js",
21
+ "engines": {
22
+ "node": ">=8.0.0"
23
+ },
24
+ "files": [
25
+ "/dist"
26
+ ],
27
+ "dependencies": {
28
+ "as-procedure": "1.1.11",
29
+ "domain-objects": "0.31.9",
30
+ "find-up": "5.0.0",
31
+ "hash-fns": "1.1.0",
32
+ "helpful-errors": "1.5.3",
33
+ "iso-time": "1.10.1",
34
+ "rhachet-artifact": "1.0.3",
35
+ "serde-fns": "1.3.0",
36
+ "type-fns": "1.21.0"
37
+ },
38
+ "devDependencies": {
39
+ "@biomejs/biome": "2.3.8",
40
+ "@commitlint/cli": "19.5.0",
41
+ "@commitlint/config-conventional": "19.5.0",
42
+ "@swc/core": "1.15.3",
43
+ "@swc/jest": "0.2.39",
44
+ "@tsconfig/node20": "20.1.5",
45
+ "@tsconfig/strictest": "2.0.5",
46
+ "@types/jest": "30.0.0",
47
+ "@types/node": "22.15.21",
48
+ "cz-conventional-changelog": "3.3.0",
49
+ "declapract": "0.13.14",
50
+ "declapract-typescript-ehmpathy": "0.47.16",
51
+ "declastruct": "1.7.3",
52
+ "declastruct-github": "1.3.0",
53
+ "depcheck": "1.4.3",
54
+ "esbuild-register": "3.6.0",
55
+ "husky": "8.0.3",
56
+ "jest": "30.2.0",
57
+ "rhachet": "1.21.3",
58
+ "rhachet-roles-bhrain": "0.5.9",
59
+ "rhachet-roles-bhuild": "0.6.3",
60
+ "rhachet-roles-ehmpathy": "1.17.15",
61
+ "test-fns": "1.5.0",
62
+ "tsc-alias": "1.8.10",
63
+ "tsx": "4.20.6",
64
+ "typescript": "5.4.5",
65
+ "yalc": "1.0.0-pre.53"
66
+ },
67
+ "config": {
68
+ "commitizen": {
69
+ "path": "./node_modules/cz-conventional-changelog"
70
+ }
71
+ },
72
+ "scripts": {
73
+ "build:ts": "tsc -p ./tsconfig.build.json",
74
+ "commit:with-cli": "npx cz",
75
+ "fix:format:biome": "biome check --write",
76
+ "fix:format": "npm run fix:format:biome",
77
+ "fix:lint": "biome check --write",
78
+ "fix": "npm run fix:format && npm run fix:lint",
79
+ "build:clean:bun": "rm -f ./bin/*.bc",
80
+ "build:clean:tsc": "(chmod -R u+w dist 2>/dev/null || true) && rm -rf dist/",
81
+ "build:clean": "npm run build:clean:tsc && npm run build:clean:bun",
82
+ "build:compile:tsc": "tsc -p ./tsconfig.build.json && tsc-alias -p ./tsconfig.build.json",
83
+ "build:compile": "npm run build:compile:tsc && npm run build:compile:bun --if-present",
84
+ "build": "npm run build:clean && npm run build:compile && npm run build:complete --if-present",
85
+ "test:commits": "LAST_TAG=$(git describe --tags --abbrev=0 @^ 2> /dev/null || git rev-list --max-parents=0 HEAD) && npx commitlint --from $LAST_TAG --to HEAD --verbose",
86
+ "test:types": "tsc -p ./tsconfig.json --noEmit",
87
+ "test:format:biome": "biome format",
88
+ "test:format": "npm run test:format:biome",
89
+ "test:lint:deps": "npx depcheck -c ./.depcheckrc.yml",
90
+ "test:lint:biome": "biome check --diagnostic-level=error",
91
+ "test:lint:biome:all": "biome check",
92
+ "test:lint": "npm run test:lint:biome && npm run test:lint:deps",
93
+ "test:unit": "jest -c ./jest.unit.config.ts --forceExit --verbose --passWithNoTests $([ -z $THOROUGH ] && echo '--changedSince=main') $([ -n $RESNAP ] && echo '--updateSnapshot')",
94
+ "test:integration": "jest -c ./jest.integration.config.ts --forceExit --verbose --passWithNoTests $([ -z $THOROUGH ] && echo '--changedSince=main') $([ -n $RESNAP ] && echo '--updateSnapshot')",
95
+ "test:acceptance:locally": "npm run build && LOCALLY=true jest -c ./jest.acceptance.config.ts --forceExit --verbose --runInBand --passWithNoTests $([ -n $RESNAP ] && echo '--updateSnapshot')",
96
+ "test": "npm run test:commits && npm run test:types && npm run test:format && npm run test:lint && npm run test:unit && npm run test:integration && npm run test:acceptance:locally",
97
+ "test:acceptance": "npm run build && jest -c ./jest.acceptance.config.ts --forceExit --verbose --runInBand --passWithNoTests $([ -n $RESNAP ] && echo '--updateSnapshot')",
98
+ "prepush": "npm run test && npm run build",
99
+ "prepublish": "npm run build",
100
+ "preversion": "npm run prepush",
101
+ "postversion": "git push origin HEAD --tags --no-verify",
102
+ "prepare:husky": "husky install && chmod ug+x .husky/*",
103
+ "prepare:rhachet": "rhachet init --mode upsert && rhachet roles link --repo ehmpathy --role mechanic && rhachet roles link --repo bhuild --role behaver && rhachet roles link --repo bhrain --role reviewer && rhachet roles init --role mechanic && rhachet roles init --role behaver"
104
+ }
105
+ }
package/readme.md ADDED
@@ -0,0 +1,110 @@
1
+ # emoji-space-shim
2
+
3
+ shim console.log to fix emoji space render issues across terminals.
4
+
5
+ ## problem
6
+
7
+ some emojis render incorrectly across different terminals due to character width inconsistencies. for example, the beaver emoji (`🦫`) may appear to "eat" the space after it in VS Code's terminal, while it renders correctly in other terminals.
8
+
9
+ ## solution
10
+
11
+ this package provides a shim that automatically adjusts space after emojis based on the detected terminal. this ensures consistent visual output.
12
+
13
+ ## install
14
+
15
+ ```sh
16
+ npm install emoji-space-shim
17
+ ```
18
+
19
+ ## usage
20
+
21
+ ### basic usage
22
+
23
+ ```ts
24
+ import { shimConsoleLog } from 'emoji-space-shim';
25
+
26
+ // apply the shim (auto-detects terminal)
27
+ const shim = shimConsoleLog();
28
+
29
+ // console.log now adjusts emoji space automatically
30
+ console.log('🦫 hello world');
31
+
32
+ // restore original behavior when done
33
+ shim.restore();
34
+ ```
35
+
36
+ ### explicit terminal
37
+
38
+ ```ts
39
+ import { shimConsoleLog } from 'emoji-space-shim';
40
+
41
+ // specify terminal explicitly
42
+ const shim = shimConsoleLog({ terminal: 'vscode' });
43
+
44
+ console.log('🦫 hello world'); // outputs: "🦫 hello world" (extra space added)
45
+ ```
46
+
47
+ ### scoped usage with automatic cleanup
48
+
49
+ ```ts
50
+ import { withEmojiSpaceShim } from 'emoji-space-shim';
51
+
52
+ // shim is applied for duration of logic, then automatically restored
53
+ const result = await withEmojiSpaceShim({
54
+ logic: async () => {
55
+ console.log('🦫 hello world'); // emoji space adjusted
56
+ return await doWork();
57
+ },
58
+ });
59
+
60
+ // console.log is restored to original behavior here
61
+ console.log('normal log'); // no emoji adjustment
62
+ ```
63
+
64
+ this is useful when you want to:
65
+ - ensure the shim is always cleaned up (even if errors occur)
66
+ - scope the shim to a specific block of code
67
+ - avoid manual restore() calls
68
+
69
+ ## terminal support
70
+
71
+ | terminal | detection |
72
+ | -------- | ----------------------------------- |
73
+ | vscode | `TERM_PROGRAM === 'vscode'` |
74
+ | xterm | `TERM.includes('xterm')` |
75
+ | gnome | `TERM_PROGRAM === 'gnome-terminal'` |
76
+ | default | fallback |
77
+
78
+ ## extend the registry
79
+
80
+ you can extend the emoji registry for custom emoji support:
81
+
82
+ ```ts
83
+ import { EMOJI_SPACE_REGISTRY, shimConsoleLog } from 'emoji-space-shim';
84
+
85
+ // add custom emoji rules
86
+ EMOJI_SPACE_REGISTRY['🎉'] = { vscode: 1, default: 0 };
87
+
88
+ // now shim will handle this emoji too
89
+ const shim = shimConsoleLog();
90
+ console.log('🎉 celebration');
91
+ ```
92
+
93
+ ## exports
94
+
95
+ | export | description |
96
+ | ----------------------------- | ---------------------------------- |
97
+ | `shimConsoleLog` | main shim function |
98
+ | `withEmojiSpaceShim` | scoped wrapper with auto-cleanup |
99
+ | `TerminalChoice` | type for terminal variants |
100
+ | `EMOJI_SPACE_REGISTRY` | emoji space rules dictionary |
101
+ | `detectTerminalChoice` | terminal detection function |
102
+ | `computeSpaceAdjustment` | space calculation function |
103
+ | `transformMessageForTerminal` | message transform function |
104
+
105
+ ## how it works
106
+
107
+ 1. `detectTerminalChoice()` determines the current terminal from environment variables
108
+ 2. `computeSpaceAdjustment()` looks up the required space for each emoji in the registry
109
+ 3. `transformMessageForTerminal()` applies the space adjustments to strings
110
+ 4. `shimConsoleLog()` wraps `console.log` to automatically transform all string arguments