motd-tool 1.0.2
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/Formula/motd-tool.rb +28 -0
- package/LICENSE +21 -0
- package/README.md +184 -0
- package/bin/xmotd.js +9 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +144 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/hook.d.ts +6 -0
- package/dist/src/hook.js +57 -0
- package/dist/src/hook.js.map +1 -0
- package/dist/src/store.d.ts +31 -0
- package/dist/src/store.js +153 -0
- package/dist/src/store.js.map +1 -0
- package/dist/test/cli.test.d.ts +1 -0
- package/dist/test/cli.test.js +101 -0
- package/dist/test/cli.test.js.map +1 -0
- package/package.json +49 -0
- package/scripts/postinstall.js +15 -0
- package/scripts/prepare-release.mjs +26 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class MotdTool < Formula
|
|
2
|
+
desc "Tiny CLI that prints a random message of the day in your terminal"
|
|
3
|
+
homepage "https://github.com/AlucPro/motd-tool"
|
|
4
|
+
url "https://registry.npmjs.org/motd-tool/-/motd-tool-1.0.2.tgz"
|
|
5
|
+
sha256 "08afc5723eb1086d95e6a0752c168b324d708bf3ef0761d4effbb39eac2c1bc4"
|
|
6
|
+
license "MIT"
|
|
7
|
+
|
|
8
|
+
depends_on "node"
|
|
9
|
+
|
|
10
|
+
def install
|
|
11
|
+
libexec.install Dir["*"]
|
|
12
|
+
(bin/"xmotd").write_env_script libexec/"bin/xmotd.js", PATH => "#{Formula["node"].opt_bin}:#{ENV["PATH"]}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def caveats
|
|
16
|
+
<<~EOS
|
|
17
|
+
Run:
|
|
18
|
+
xmotd init
|
|
19
|
+
|
|
20
|
+
to enable automatic once-per-day terminal messages in your shell.
|
|
21
|
+
EOS
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test do
|
|
25
|
+
output = shell_output("#{bin}/xmotd --help")
|
|
26
|
+
assert_match "xmotd - tiny message of the day CLI", output
|
|
27
|
+
end
|
|
28
|
+
end
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 πΌπππ
|
|
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/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# motd-tool
|
|
2
|
+
|
|
3
|
+
Tiny CLI that prints a random message of the day in your terminal.
|
|
4
|
+
|
|
5
|
+
`xmotd` is built for developers who live in the shell and want something lighter than a dashboard, but more personal than a static prompt.
|
|
6
|
+
|
|
7
|
+
## Why people install it
|
|
8
|
+
|
|
9
|
+
- `xmotd` prints a random line from your own local message library
|
|
10
|
+
- `xmotd init` shows one message automatically on the first terminal session of each day
|
|
11
|
+
- `xmotd add`, `remove`, `list`, `import`, and `export` keep the message library simple
|
|
12
|
+
- It is local-first, fast, and dependency-light at runtime
|
|
13
|
+
|
|
14
|
+
## Quick look
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
$ xmotd
|
|
18
|
+
Stay hungry, stay foolish.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
$ xmotd add "Code is poetry"
|
|
23
|
+
Added: Code is poetry
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
$ xmotd list
|
|
28
|
+
1. Stay hungry, stay foolish.
|
|
29
|
+
2. Code is poetry
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
$ xmotd remove 2
|
|
34
|
+
Removed #2: Code is poetry
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
Install from npm:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install -g motd-tool
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Install from Homebrew:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
brew install AlucPro/tap/motd-tool
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For local development, this repository uses `pnpm` and TypeScript:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pnpm install
|
|
55
|
+
pnpm check
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
Print a random message:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
xmotd
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Add a message:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
xmotd add "Ship small, ship often"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Remove a message by index or exact text:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
xmotd remove 2
|
|
76
|
+
xmotd remove "Ship small, ship often"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
List all messages:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
xmotd list
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Import messages from `.txt` or `.json`:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
xmotd import ./messages.txt
|
|
89
|
+
xmotd import ./messages.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Export your current library:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
xmotd export ./backup.json
|
|
96
|
+
xmotd export ./backup.txt
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Enable once-per-day automatic output in your shell:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
xmotd init
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Preview the shell hook:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
xmotd hook
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
See where files are stored:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
xmotd paths
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Default behavior
|
|
118
|
+
|
|
119
|
+
After installation, `xmotd` starts with one built-in message:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
Stay hungry, stay foolish.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Every manual `xmotd` run selects a random message from your local library.
|
|
126
|
+
|
|
127
|
+
The automatic shell hook uses a separate state file so the message only appears once per local calendar day.
|
|
128
|
+
|
|
129
|
+
## Message storage
|
|
130
|
+
|
|
131
|
+
`xmotd` stores data in standard XDG-style locations:
|
|
132
|
+
|
|
133
|
+
- Config: `~/.config/motd-tool/messages.json`
|
|
134
|
+
- State: `~/.local/state/motd-tool/state.json`
|
|
135
|
+
|
|
136
|
+
You can override these with `XDG_CONFIG_HOME` and `XDG_STATE_HOME`.
|
|
137
|
+
|
|
138
|
+
## Release workflow
|
|
139
|
+
|
|
140
|
+
Project maintainers can use:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pnpm release:check
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`pnpm release:check` runs build and tests, then updates the Homebrew formula SHA based on the npm tarball.
|
|
147
|
+
|
|
148
|
+
Release flow:
|
|
149
|
+
|
|
150
|
+
1. Update `package.json` version
|
|
151
|
+
2. Commit the release changes
|
|
152
|
+
3. Push `main`
|
|
153
|
+
4. Create and push a matching tag such as `v1.0.1`
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
git add .
|
|
157
|
+
git commit -m "release: v1.0.1"
|
|
158
|
+
git push origin main
|
|
159
|
+
git tag v1.0.1
|
|
160
|
+
git push origin v1.0.1
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
When the tag lands on GitHub, the `Release` workflow will:
|
|
164
|
+
|
|
165
|
+
- build and test the project
|
|
166
|
+
- publish `motd-tool` to npm with `NPM_TOKEN`
|
|
167
|
+
- rebuild the Homebrew formula with the new npm tarball SHA
|
|
168
|
+
- push `Formula/motd-tool.rb` to `AlucPro/homebrew-tap` with `HOMEBREW_TAP_TOKEN`
|
|
169
|
+
- create a GitHub Release with the packaged tarball
|
|
170
|
+
|
|
171
|
+
GitHub Actions included in this repo:
|
|
172
|
+
|
|
173
|
+
- `CI`: install, build, test, and pack on pushes and pull requests
|
|
174
|
+
- `Release`: publish to npm, update the Homebrew tap, and attach the package tarball when a `v*` tag is pushed
|
|
175
|
+
|
|
176
|
+
## Contributing
|
|
177
|
+
|
|
178
|
+
Issues and pull requests are welcome.
|
|
179
|
+
|
|
180
|
+
The easiest way to contribute is to improve the default message set, shell support, and installation experience.
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT
|
package/bin/xmotd.js
ADDED
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.maybePrintAutoMessage = maybePrintAutoMessage;
|
|
7
|
+
exports.run = run;
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const hook_1 = require("./hook");
|
|
10
|
+
const store_1 = require("./store");
|
|
11
|
+
function printHelp() {
|
|
12
|
+
console.log(`xmotd - tiny message of the day CLI
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
xmotd
|
|
16
|
+
xmotd add "Your message"
|
|
17
|
+
xmotd remove <index|exact message>
|
|
18
|
+
xmotd list
|
|
19
|
+
xmotd import <file.json|file.txt>
|
|
20
|
+
xmotd export <file.json|file.txt>
|
|
21
|
+
xmotd init [zsh|bash|fish]
|
|
22
|
+
xmotd hook [zsh|bash|fish]
|
|
23
|
+
xmotd paths
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
--auto Print only on the first terminal session of the day
|
|
27
|
+
-h, --help
|
|
28
|
+
-v, --version`);
|
|
29
|
+
}
|
|
30
|
+
function printVersion() {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
32
|
+
const pkg = require(node_path_1.default.join(__dirname, "..", "..", "package.json"));
|
|
33
|
+
console.log(pkg.version);
|
|
34
|
+
}
|
|
35
|
+
function todayIsoDate() {
|
|
36
|
+
const now = new Date();
|
|
37
|
+
const year = now.getFullYear();
|
|
38
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
39
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
40
|
+
return `${year}-${month}-${day}`;
|
|
41
|
+
}
|
|
42
|
+
function printRandomMessage() {
|
|
43
|
+
(0, store_1.ensureStore)();
|
|
44
|
+
console.log((0, store_1.pickRandomMessage)());
|
|
45
|
+
}
|
|
46
|
+
function maybePrintAutoMessage() {
|
|
47
|
+
(0, store_1.ensureStore)();
|
|
48
|
+
const today = todayIsoDate();
|
|
49
|
+
const state = (0, store_1.getState)();
|
|
50
|
+
if (state.lastShownOn === today) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
console.log((0, store_1.pickRandomMessage)());
|
|
54
|
+
(0, store_1.setLastShownOn)(today);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
function printMessages() {
|
|
58
|
+
(0, store_1.getMessages)().forEach((message, index) => {
|
|
59
|
+
console.log(`${index + 1}. ${message}`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function handleInit(shellName) {
|
|
63
|
+
const shell = shellName || node_path_1.default.basename(process.env.SHELL || "");
|
|
64
|
+
const result = (0, hook_1.installHook)(shell);
|
|
65
|
+
if (result.changed) {
|
|
66
|
+
console.log(`Installed xmotd shell hook in ${result.rcFile}`);
|
|
67
|
+
console.log("Open a new terminal to see the first message of each day.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
console.log(`xmotd shell hook already exists in ${result.rcFile}`);
|
|
71
|
+
}
|
|
72
|
+
function handlePaths() {
|
|
73
|
+
const paths = (0, store_1.getPaths)();
|
|
74
|
+
console.log(`config: ${paths.configDir}`);
|
|
75
|
+
console.log(`messages: ${paths.messagesFile}`);
|
|
76
|
+
console.log(`state: ${paths.stateFile}`);
|
|
77
|
+
console.log(`shellrc: ${(0, hook_1.resolveRcFile)()}`);
|
|
78
|
+
}
|
|
79
|
+
async function run(argv) {
|
|
80
|
+
const [command, ...rest] = argv;
|
|
81
|
+
if (!command) {
|
|
82
|
+
printRandomMessage();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (command === "--auto") {
|
|
86
|
+
maybePrintAutoMessage();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (command === "-h" || command === "--help" || command === "help") {
|
|
90
|
+
printHelp();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (command === "-v" || command === "--version" || command === "version") {
|
|
94
|
+
printVersion();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (command === "add") {
|
|
98
|
+
const added = (0, store_1.addMessage)(rest.join(" ").trim());
|
|
99
|
+
console.log(`Added: ${added}`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (command === "remove") {
|
|
103
|
+
const target = rest.join(" ").trim();
|
|
104
|
+
const result = (0, store_1.removeMessage)(target);
|
|
105
|
+
console.log(`Removed #${result.index + 1}: ${result.removed}`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (command === "list") {
|
|
109
|
+
printMessages();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (command === "import") {
|
|
113
|
+
const filePath = rest[0];
|
|
114
|
+
if (!filePath) {
|
|
115
|
+
throw new Error("import requires a file path");
|
|
116
|
+
}
|
|
117
|
+
const result = (0, store_1.importMessages)(filePath);
|
|
118
|
+
console.log(`Imported ${result.imported} message(s). Total: ${result.total}`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (command === "export") {
|
|
122
|
+
const filePath = rest[0];
|
|
123
|
+
if (!filePath) {
|
|
124
|
+
throw new Error("export requires a file path");
|
|
125
|
+
}
|
|
126
|
+
const result = (0, store_1.exportMessages)(filePath);
|
|
127
|
+
console.log(`Exported ${result.count} message(s) to ${result.filePath}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (command === "init") {
|
|
131
|
+
handleInit(rest[0]);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (command === "hook") {
|
|
135
|
+
console.log((0, hook_1.getHookScript)(rest[0]));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (command === "paths") {
|
|
139
|
+
handlePaths();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
throw new Error(`unknown command "${command}"`);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/src/hook.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveRcFile = resolveRcFile;
|
|
7
|
+
exports.getHookScript = getHookScript;
|
|
8
|
+
exports.installHook = installHook;
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const HOOK_BEGIN = "# >>> xmotd >>>";
|
|
13
|
+
const HOOK_END = "# <<< xmotd <<<";
|
|
14
|
+
function resolveRcFile(shellName) {
|
|
15
|
+
const home = node_os_1.default.homedir();
|
|
16
|
+
const shell = shellName || node_path_1.default.basename(process.env.SHELL || "");
|
|
17
|
+
if (shell === "bash") {
|
|
18
|
+
const bashProfile = node_path_1.default.join(home, ".bash_profile");
|
|
19
|
+
return node_fs_1.default.existsSync(bashProfile) ? bashProfile : node_path_1.default.join(home, ".bashrc");
|
|
20
|
+
}
|
|
21
|
+
if (shell === "fish") {
|
|
22
|
+
return node_path_1.default.join(home, ".config", "fish", "config.fish");
|
|
23
|
+
}
|
|
24
|
+
return node_path_1.default.join(home, ".zshrc");
|
|
25
|
+
}
|
|
26
|
+
function getHookScript(shellName) {
|
|
27
|
+
const shell = shellName || node_path_1.default.basename(process.env.SHELL || "");
|
|
28
|
+
if (shell === "fish") {
|
|
29
|
+
return [
|
|
30
|
+
HOOK_BEGIN,
|
|
31
|
+
"if status is-interactive",
|
|
32
|
+
" xmotd --auto 2>/dev/null; or true",
|
|
33
|
+
"end",
|
|
34
|
+
HOOK_END
|
|
35
|
+
].join("\n");
|
|
36
|
+
}
|
|
37
|
+
return [
|
|
38
|
+
HOOK_BEGIN,
|
|
39
|
+
'if [ -n "$PS1" ]; then',
|
|
40
|
+
" xmotd --auto 2>/dev/null || true",
|
|
41
|
+
"fi",
|
|
42
|
+
HOOK_END
|
|
43
|
+
].join("\n");
|
|
44
|
+
}
|
|
45
|
+
function installHook(shellName) {
|
|
46
|
+
const rcFile = resolveRcFile(shellName);
|
|
47
|
+
const hook = getHookScript(shellName);
|
|
48
|
+
const existing = node_fs_1.default.existsSync(rcFile) ? node_fs_1.default.readFileSync(rcFile, "utf8") : "";
|
|
49
|
+
if (existing.includes(HOOK_BEGIN)) {
|
|
50
|
+
return { rcFile, changed: false };
|
|
51
|
+
}
|
|
52
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(rcFile), { recursive: true });
|
|
53
|
+
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
54
|
+
node_fs_1.default.writeFileSync(rcFile, `${existing}${prefix}${hook}\n`, "utf8");
|
|
55
|
+
return { rcFile, changed: true };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/hook.ts"],"names":[],"mappings":";;;;;AAOA,sCAcC;AAED,sCAoBC;AAED,kCAcC;AA3DD,sDAAyB;AACzB,sDAAyB;AACzB,0DAA6B;AAE7B,MAAM,UAAU,GAAG,iBAAiB,CAAC;AACrC,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAEnC,SAAgB,aAAa,CAAC,SAAkB;IAC9C,MAAM,IAAI,GAAG,iBAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,SAAS,IAAI,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAElE,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,MAAM,WAAW,GAAG,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACrD,OAAO,iBAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,aAAa,CAAC,SAAkB;IAC9C,MAAM,KAAK,GAAG,SAAS,IAAI,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAElE,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO;YACL,UAAU;YACV,0BAA0B;YAC1B,qCAAqC;YACrC,KAAK;YACL,QAAQ;SACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,OAAO;QACL,UAAU;QACV,wBAAwB;QACxB,oCAAoC;QACpC,IAAI;QACJ,QAAQ;KACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,WAAW,CAAC,SAAkB;IAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9E,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IAED,iBAAE,CAAC,SAAS,CAAC,mBAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,iBAAE,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC;IAElE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type StorePaths = {
|
|
2
|
+
configDir: string;
|
|
3
|
+
stateDir: string;
|
|
4
|
+
messagesFile: string;
|
|
5
|
+
stateFile: string;
|
|
6
|
+
};
|
|
7
|
+
type DisplayState = {
|
|
8
|
+
lastShownOn: string | null;
|
|
9
|
+
};
|
|
10
|
+
export declare const APP_NAME = "motd-tool";
|
|
11
|
+
export declare const DEFAULT_MESSAGE = "Stay hungry, stay foolish.";
|
|
12
|
+
export declare function getPaths(): StorePaths;
|
|
13
|
+
export declare function ensureStore(): StorePaths;
|
|
14
|
+
export declare function getMessages(): string[];
|
|
15
|
+
export declare function addMessage(message: string): string;
|
|
16
|
+
export declare function removeMessage(input: string): {
|
|
17
|
+
removed: string;
|
|
18
|
+
index: number;
|
|
19
|
+
};
|
|
20
|
+
export declare function importMessages(filePath: string): {
|
|
21
|
+
imported: number;
|
|
22
|
+
total: number;
|
|
23
|
+
};
|
|
24
|
+
export declare function exportMessages(filePath: string): {
|
|
25
|
+
filePath: string;
|
|
26
|
+
count: number;
|
|
27
|
+
};
|
|
28
|
+
export declare function pickRandomMessage(): string;
|
|
29
|
+
export declare function getState(): DisplayState;
|
|
30
|
+
export declare function setLastShownOn(isoDate: string): void;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_MESSAGE = exports.APP_NAME = void 0;
|
|
7
|
+
exports.getPaths = getPaths;
|
|
8
|
+
exports.ensureStore = ensureStore;
|
|
9
|
+
exports.getMessages = getMessages;
|
|
10
|
+
exports.addMessage = addMessage;
|
|
11
|
+
exports.removeMessage = removeMessage;
|
|
12
|
+
exports.importMessages = importMessages;
|
|
13
|
+
exports.exportMessages = exportMessages;
|
|
14
|
+
exports.pickRandomMessage = pickRandomMessage;
|
|
15
|
+
exports.getState = getState;
|
|
16
|
+
exports.setLastShownOn = setLastShownOn;
|
|
17
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
18
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
19
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
20
|
+
exports.APP_NAME = "motd-tool";
|
|
21
|
+
exports.DEFAULT_MESSAGE = "Stay hungry, stay foolish.";
|
|
22
|
+
function resolveConfigHome() {
|
|
23
|
+
return process.env.XDG_CONFIG_HOME || node_path_1.default.join(node_os_1.default.homedir(), ".config");
|
|
24
|
+
}
|
|
25
|
+
function resolveStateHome() {
|
|
26
|
+
return process.env.XDG_STATE_HOME || node_path_1.default.join(node_os_1.default.homedir(), ".local", "state");
|
|
27
|
+
}
|
|
28
|
+
function ensureDir(dirPath) {
|
|
29
|
+
node_fs_1.default.mkdirSync(dirPath, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
function writeJson(filePath, value) {
|
|
32
|
+
node_fs_1.default.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
33
|
+
}
|
|
34
|
+
function readJson(filePath, fallbackValue) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(node_fs_1.default.readFileSync(filePath, "utf8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return fallbackValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function normalizeMessages(messages) {
|
|
43
|
+
const normalized = messages
|
|
44
|
+
.map((message) => String(message).trim())
|
|
45
|
+
.filter(Boolean);
|
|
46
|
+
return normalized.length > 0 ? normalized : [exports.DEFAULT_MESSAGE];
|
|
47
|
+
}
|
|
48
|
+
function getPaths() {
|
|
49
|
+
const configDir = node_path_1.default.join(resolveConfigHome(), exports.APP_NAME);
|
|
50
|
+
const stateDir = node_path_1.default.join(resolveStateHome(), exports.APP_NAME);
|
|
51
|
+
return {
|
|
52
|
+
configDir,
|
|
53
|
+
stateDir,
|
|
54
|
+
messagesFile: node_path_1.default.join(configDir, "messages.json"),
|
|
55
|
+
stateFile: node_path_1.default.join(stateDir, "state.json")
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function ensureStore() {
|
|
59
|
+
const paths = getPaths();
|
|
60
|
+
ensureDir(paths.configDir);
|
|
61
|
+
ensureDir(paths.stateDir);
|
|
62
|
+
if (!node_fs_1.default.existsSync(paths.messagesFile)) {
|
|
63
|
+
writeJson(paths.messagesFile, { messages: [exports.DEFAULT_MESSAGE] });
|
|
64
|
+
}
|
|
65
|
+
if (!node_fs_1.default.existsSync(paths.stateFile)) {
|
|
66
|
+
writeJson(paths.stateFile, { lastShownOn: null });
|
|
67
|
+
}
|
|
68
|
+
return paths;
|
|
69
|
+
}
|
|
70
|
+
function getMessages() {
|
|
71
|
+
const { messagesFile } = ensureStore();
|
|
72
|
+
const data = readJson(messagesFile, { messages: [exports.DEFAULT_MESSAGE] });
|
|
73
|
+
return normalizeMessages(Array.isArray(data.messages) ? data.messages : [exports.DEFAULT_MESSAGE]);
|
|
74
|
+
}
|
|
75
|
+
function saveMessages(messages) {
|
|
76
|
+
const { messagesFile } = ensureStore();
|
|
77
|
+
writeJson(messagesFile, { messages });
|
|
78
|
+
}
|
|
79
|
+
function addMessage(message) {
|
|
80
|
+
const nextMessage = String(message).trim();
|
|
81
|
+
if (!nextMessage) {
|
|
82
|
+
throw new Error("message cannot be empty");
|
|
83
|
+
}
|
|
84
|
+
const messages = getMessages();
|
|
85
|
+
messages.push(nextMessage);
|
|
86
|
+
saveMessages(messages);
|
|
87
|
+
return nextMessage;
|
|
88
|
+
}
|
|
89
|
+
function removeMessage(input) {
|
|
90
|
+
const target = String(input).trim();
|
|
91
|
+
if (!target) {
|
|
92
|
+
throw new Error("remove requires an index or exact message");
|
|
93
|
+
}
|
|
94
|
+
const messages = getMessages();
|
|
95
|
+
let index = Number.NaN;
|
|
96
|
+
if (/^\d+$/.test(target)) {
|
|
97
|
+
index = Number(target) - 1;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
index = messages.findIndex((message) => message === target);
|
|
101
|
+
}
|
|
102
|
+
if (index < 0 || index >= messages.length) {
|
|
103
|
+
throw new Error(`message not found: ${target}`);
|
|
104
|
+
}
|
|
105
|
+
const [removed] = messages.splice(index, 1);
|
|
106
|
+
saveMessages(messages.length > 0 ? messages : [exports.DEFAULT_MESSAGE]);
|
|
107
|
+
return { removed, index };
|
|
108
|
+
}
|
|
109
|
+
function importMessages(filePath) {
|
|
110
|
+
const sourcePath = node_path_1.default.resolve(filePath);
|
|
111
|
+
const raw = node_fs_1.default.readFileSync(sourcePath, "utf8");
|
|
112
|
+
const imported = sourcePath.endsWith(".json")
|
|
113
|
+
? parseJsonMessages(raw)
|
|
114
|
+
: raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
115
|
+
if (imported.length === 0) {
|
|
116
|
+
throw new Error("no messages found in import file");
|
|
117
|
+
}
|
|
118
|
+
const current = getMessages();
|
|
119
|
+
const merged = Array.from(new Set([...current, ...imported]));
|
|
120
|
+
saveMessages(merged);
|
|
121
|
+
return { imported: merged.length - current.length, total: merged.length };
|
|
122
|
+
}
|
|
123
|
+
function exportMessages(filePath) {
|
|
124
|
+
const destinationPath = node_path_1.default.resolve(filePath);
|
|
125
|
+
const messages = getMessages();
|
|
126
|
+
const content = destinationPath.endsWith(".json")
|
|
127
|
+
? `${JSON.stringify(messages, null, 2)}\n`
|
|
128
|
+
: `${messages.join("\n")}\n`;
|
|
129
|
+
ensureDir(node_path_1.default.dirname(destinationPath));
|
|
130
|
+
node_fs_1.default.writeFileSync(destinationPath, content, "utf8");
|
|
131
|
+
return { filePath: destinationPath, count: messages.length };
|
|
132
|
+
}
|
|
133
|
+
function parseJsonMessages(raw) {
|
|
134
|
+
const parsed = JSON.parse(raw);
|
|
135
|
+
if (!Array.isArray(parsed)) {
|
|
136
|
+
throw new Error("JSON import file must be an array of strings");
|
|
137
|
+
}
|
|
138
|
+
return parsed.map((message) => String(message).trim()).filter(Boolean);
|
|
139
|
+
}
|
|
140
|
+
function pickRandomMessage() {
|
|
141
|
+
const messages = getMessages();
|
|
142
|
+
const index = Math.floor(Math.random() * messages.length);
|
|
143
|
+
return messages[index];
|
|
144
|
+
}
|
|
145
|
+
function getState() {
|
|
146
|
+
const { stateFile } = ensureStore();
|
|
147
|
+
return readJson(stateFile, { lastShownOn: null });
|
|
148
|
+
}
|
|
149
|
+
function setLastShownOn(isoDate) {
|
|
150
|
+
const { stateFile } = ensureStore();
|
|
151
|
+
writeJson(stateFile, { lastShownOn: isoDate });
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":";;;;;;AAsDA,4BAUC;AAED,kCAcC;AAED,kCAIC;AAOD,gCAUC;AAED,sCAsBC;AAED,wCAeC;AAED,wCAUC;AAWD,8CAIC;AAED,4BAGC;AAED,wCAGC;AArLD,sDAAyB;AACzB,sDAAyB;AACzB,0DAA6B;AAiBhB,QAAA,QAAQ,GAAG,WAAW,CAAC;AACvB,QAAA,eAAe,GAAG,4BAA4B,CAAC;AAE5D,SAAS,iBAAiB;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,SAAS,CAAC,OAAe;IAChC,iBAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB,EAAE,KAAc;IACjD,iBAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,QAAQ,CAAI,QAAgB,EAAE,aAAgB;IACrD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAM,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAAC;IACvB,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAmB;IAC5C,MAAM,UAAU,GAAG,QAAQ;SACxB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACxC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,uBAAe,CAAC,CAAC;AAChE,CAAC;AAED,SAAgB,QAAQ;IACtB,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,gBAAQ,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,gBAAQ,CAAC,CAAC;IAEzD,OAAO;QACL,SAAS;QACT,QAAQ;QACR,YAAY,EAAE,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC;QACnD,SAAS,EAAE,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW;IACzB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3B,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE1B,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,SAAS,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,uBAAe,CAAC,EAAyB,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACpC,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,IAAI,EAAyB,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,WAAW;IACzB,MAAM,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAe,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,uBAAe,CAAC,EAAE,CAAC,CAAC;IACnF,OAAO,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,uBAAe,CAAC,CAAC,CAAC;AAC7F,CAAC;AAED,SAAS,YAAY,CAAC,QAAkB;IACtC,MAAM,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,CAAC;IACvC,SAAS,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,UAAU,CAAC,OAAe;IACxC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvB,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAgB,aAAa,CAAC,KAAa;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC;IAEvB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5C,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,uBAAe,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,SAAgB,cAAc,CAAC,QAAgB;IAC7C,MAAM,UAAU,GAAG,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,iBAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC3C,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC;QACxB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9D,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AAC5E,CAAC;AAED,SAAgB,cAAc,CAAC,QAAgB;IAC7C,MAAM,eAAe,GAAG,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC/C,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;QAC1C,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAE/B,SAAS,CAAC,mBAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IACzC,iBAAE,CAAC,aAAa,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACzE,CAAC;AAED,SAAgB,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1D,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,SAAgB,QAAQ;IACtB,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;IACpC,OAAO,QAAQ,CAAe,SAAS,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,SAAgB,cAAc,CAAC,OAAe;IAC5C,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;IACpC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,OAAO,EAAyB,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
40
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
41
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
42
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
43
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
44
|
+
function createTempHomes() {
|
|
45
|
+
const root = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), "xmotd-"));
|
|
46
|
+
const config = node_path_1.default.join(root, "config");
|
|
47
|
+
const state = node_path_1.default.join(root, "state");
|
|
48
|
+
process.env.XDG_CONFIG_HOME = config;
|
|
49
|
+
process.env.XDG_STATE_HOME = state;
|
|
50
|
+
return { root, config, state };
|
|
51
|
+
}
|
|
52
|
+
(0, node_test_1.default)("store initializes with a default message", async () => {
|
|
53
|
+
createTempHomes();
|
|
54
|
+
const { getMessages } = await Promise.resolve().then(() => __importStar(require("../src/store")));
|
|
55
|
+
const messages = getMessages();
|
|
56
|
+
strict_1.default.equal(messages.length, 1);
|
|
57
|
+
strict_1.default.equal(messages[0], "Stay hungry, stay foolish.");
|
|
58
|
+
});
|
|
59
|
+
(0, node_test_1.default)("add appends messages to the local store", async () => {
|
|
60
|
+
createTempHomes();
|
|
61
|
+
const { addMessage, getMessages } = await Promise.resolve().then(() => __importStar(require("../src/store")));
|
|
62
|
+
addMessage("Code is poetry");
|
|
63
|
+
const messages = getMessages();
|
|
64
|
+
strict_1.default.deepEqual(messages, ["Stay hungry, stay foolish.", "Code is poetry"]);
|
|
65
|
+
});
|
|
66
|
+
(0, node_test_1.default)("remove accepts an index", async () => {
|
|
67
|
+
createTempHomes();
|
|
68
|
+
const { addMessage, getMessages, removeMessage } = await Promise.resolve().then(() => __importStar(require("../src/store")));
|
|
69
|
+
addMessage("Code is poetry");
|
|
70
|
+
const removed = removeMessage("2");
|
|
71
|
+
strict_1.default.equal(removed.removed, "Code is poetry");
|
|
72
|
+
strict_1.default.deepEqual(getMessages(), ["Stay hungry, stay foolish."]);
|
|
73
|
+
});
|
|
74
|
+
(0, node_test_1.default)("import/export handles text files", async () => {
|
|
75
|
+
const { root } = createTempHomes();
|
|
76
|
+
const { exportMessages, importMessages, getMessages } = await Promise.resolve().then(() => __importStar(require("../src/store")));
|
|
77
|
+
const importFile = node_path_1.default.join(root, "messages.txt");
|
|
78
|
+
const exportFile = node_path_1.default.join(root, "export.json");
|
|
79
|
+
node_fs_1.default.writeFileSync(importFile, "Code is poetry\nShip it\n", "utf8");
|
|
80
|
+
const imported = importMessages(importFile);
|
|
81
|
+
const exported = exportMessages(exportFile);
|
|
82
|
+
strict_1.default.equal(imported.imported, 2);
|
|
83
|
+
strict_1.default.equal(exported.count, getMessages().length);
|
|
84
|
+
strict_1.default.deepEqual(JSON.parse(node_fs_1.default.readFileSync(exportFile, "utf8")), getMessages());
|
|
85
|
+
});
|
|
86
|
+
(0, node_test_1.default)("auto mode only prints once per day", async () => {
|
|
87
|
+
createTempHomes();
|
|
88
|
+
const { maybePrintAutoMessage } = await Promise.resolve().then(() => __importStar(require("../src/cli")));
|
|
89
|
+
const logs = [];
|
|
90
|
+
const originalLog = console.log;
|
|
91
|
+
console.log = (value) => logs.push(String(value));
|
|
92
|
+
try {
|
|
93
|
+
strict_1.default.equal(maybePrintAutoMessage(), true);
|
|
94
|
+
strict_1.default.equal(maybePrintAutoMessage(), false);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
console.log = originalLog;
|
|
98
|
+
}
|
|
99
|
+
strict_1.default.equal(logs.length, 1);
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=cli.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../../test/cli.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "motd-tool",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Tiny CLI that prints a random message of the day in your terminal.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "AlucPro",
|
|
7
|
+
"homepage": "https://github.com/AlucPro/motd-tool",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/AlucPro/motd-tool.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/AlucPro/motd-tool/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"motd",
|
|
17
|
+
"cli",
|
|
18
|
+
"terminal",
|
|
19
|
+
"shell",
|
|
20
|
+
"inspiration"
|
|
21
|
+
],
|
|
22
|
+
"type": "commonjs",
|
|
23
|
+
"bin": {
|
|
24
|
+
"xmotd": "./bin/xmotd.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"bin",
|
|
28
|
+
"dist",
|
|
29
|
+
"scripts",
|
|
30
|
+
"Formula",
|
|
31
|
+
"README.md",
|
|
32
|
+
"LICENSE"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^24.0.0",
|
|
39
|
+
"typescript": "^5.8.2"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc --project tsconfig.json",
|
|
43
|
+
"check": "pnpm build && pnpm test",
|
|
44
|
+
"dev": "pnpm build --watch",
|
|
45
|
+
"postinstall": "node ./scripts/postinstall.js",
|
|
46
|
+
"release:check": "pnpm check && node ./scripts/prepare-release.mjs",
|
|
47
|
+
"test": "pnpm build && node --test dist/test/*.test.js"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const os = require("os");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
const shell = path.basename(process.env.SHELL || "");
|
|
5
|
+
const rcFile =
|
|
6
|
+
shell === "bash"
|
|
7
|
+
? path.join(os.homedir(), ".bashrc")
|
|
8
|
+
: shell === "fish"
|
|
9
|
+
? path.join(os.homedir(), ".config", "fish", "config.fish")
|
|
10
|
+
: path.join(os.homedir(), ".zshrc");
|
|
11
|
+
|
|
12
|
+
console.log("motd-tool installed.");
|
|
13
|
+
console.log('Run "xmotd" to print a random message.');
|
|
14
|
+
console.log(`Run "xmotd init ${shell || "zsh"}" to enable once-per-day terminal messages in ${rcFile}.`);
|
|
15
|
+
console.log('Run "xmotd --help" to see add/remove/import/export commands.');
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
7
|
+
const formulaPath = path.join(root, "Formula", "motd-tool.rb");
|
|
8
|
+
const version = packageJson.version;
|
|
9
|
+
const tarballName = `motd-tool-${version}.tgz`;
|
|
10
|
+
const tarballPath = path.join(root, tarballName);
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(tarballPath)) {
|
|
13
|
+
console.log(`Tarball not found: ${tarballName}`);
|
|
14
|
+
console.log("Run: pnpm pack");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const sha256 = crypto.createHash("sha256").update(fs.readFileSync(tarballPath)).digest("hex");
|
|
19
|
+
const formula = fs.readFileSync(formulaPath, "utf8")
|
|
20
|
+
.replace(/motd-tool-\d+\.\d+\.\d+\.tgz/, `motd-tool-${version}.tgz`)
|
|
21
|
+
.replace(/sha256 "[^"]+"/, `sha256 "${sha256}"`);
|
|
22
|
+
|
|
23
|
+
fs.writeFileSync(formulaPath, formula, "utf8");
|
|
24
|
+
|
|
25
|
+
console.log(`Updated Formula/motd-tool.rb for v${version}`);
|
|
26
|
+
console.log(`sha256: ${sha256}`);
|