@towles/tool 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/dist/index.d.mts +0 -4
- package/dist/index.mjs +200 -11
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ One off quality of life scripts that I use on a daily basis.
|
|
|
10
10
|
|
|
11
11
|
## Tools to add
|
|
12
12
|
- [ ] Today - creates and opens a markdown file, named the current week of the year, for you to keep your daily notes and use a scratch pad for notes.
|
|
13
|
+
- [ ] git commit with message prompt
|
|
13
14
|
|
|
14
15
|
## Install from repository
|
|
15
16
|
|
|
@@ -41,7 +42,20 @@ if that works, then you need to add the pnpm global bin directory to your PATH.
|
|
|
41
42
|
|
|
42
43
|
## packages to consider
|
|
43
44
|
|
|
44
|
-
- [
|
|
45
|
+
- [Consola](https://github.com/unjs/consola) console wrapper and colors
|
|
46
|
+
- [c12](https://github.com/unjs/c12) configuration loader and utilities
|
|
47
|
+
|
|
48
|
+
## Document verbose and debug options
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
export DEBUG=1
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
TODO add verbose option.
|
|
55
|
+
|
|
56
|
+
## Development
|
|
57
|
+
|
|
58
|
+
For information on how releases are managed, see the [Release Process](docs/release-process.md) documentation.
|
|
45
59
|
|
|
46
60
|
## History
|
|
47
61
|
|
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,204 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import process from 'node:process';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
+
import consola from 'consola';
|
|
5
|
+
import { colors } from 'consola/utils';
|
|
6
|
+
import { exec } from 'node:child_process';
|
|
7
|
+
import { existsSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import path__default from 'node:path';
|
|
10
|
+
import util, { promisify } from 'node:util';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { setupDotenv, loadConfig } from 'c12';
|
|
13
|
+
import { updateConfig } from 'c12/update';
|
|
4
14
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const version = "0.0.7";
|
|
16
|
+
|
|
17
|
+
function getMondayOfWeek(date) {
|
|
18
|
+
const newDate = new Date(date);
|
|
19
|
+
const day = newDate.getDay();
|
|
20
|
+
const diff = newDate.getDate() - day + (day === 0 ? -6 : 1);
|
|
21
|
+
newDate.setDate(diff);
|
|
22
|
+
newDate.setHours(0, 0, 0, 0);
|
|
23
|
+
return newDate;
|
|
24
|
+
}
|
|
25
|
+
function getWeekInfo(mondayDate) {
|
|
26
|
+
const tuesdayDate = new Date(mondayDate);
|
|
27
|
+
tuesdayDate.setDate(mondayDate.getDate() + 1);
|
|
28
|
+
const wednesdayDate = new Date(mondayDate);
|
|
29
|
+
wednesdayDate.setDate(mondayDate.getDate() + 2);
|
|
30
|
+
const thursdayDate = new Date(mondayDate);
|
|
31
|
+
thursdayDate.setDate(mondayDate.getDate() + 3);
|
|
32
|
+
const fridayDate = new Date(mondayDate);
|
|
33
|
+
fridayDate.setDate(mondayDate.getDate() + 4);
|
|
34
|
+
return {
|
|
35
|
+
mondayDate,
|
|
36
|
+
tuesdayDate,
|
|
37
|
+
wednesdayDate,
|
|
38
|
+
thursdayDate,
|
|
39
|
+
fridayDate
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function formatDate(date) {
|
|
43
|
+
return date.toISOString().split("T")[0];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const execAsync = promisify(exec);
|
|
47
|
+
function ensureDirectoryExists(folderPath) {
|
|
48
|
+
if (!existsSync(folderPath)) {
|
|
49
|
+
consola.info(`Creating journal directory: ${colors.cyan(folderPath)}`);
|
|
50
|
+
mkdirSync(folderPath, { recursive: true });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function createJournalContent({ mondayDate }) {
|
|
54
|
+
const weekInfo = getWeekInfo(mondayDate);
|
|
55
|
+
const content = [`# Journal for Week ${formatDate(mondayDate)}`];
|
|
56
|
+
content.push(``);
|
|
57
|
+
content.push(`## ${formatDate(weekInfo.mondayDate)} Monday`);
|
|
58
|
+
content.push(``);
|
|
59
|
+
content.push(`## ${formatDate(weekInfo.tuesdayDate)} Tuesday`);
|
|
60
|
+
content.push(``);
|
|
61
|
+
content.push(`## ${formatDate(weekInfo.wednesdayDate)} Wednesday`);
|
|
62
|
+
content.push(``);
|
|
63
|
+
content.push(`## ${formatDate(weekInfo.thursdayDate)} Thursday`);
|
|
64
|
+
content.push(``);
|
|
65
|
+
content.push(`## ${formatDate(weekInfo.fridayDate)} Friday`);
|
|
66
|
+
content.push(``);
|
|
67
|
+
return content.join("\n");
|
|
68
|
+
}
|
|
69
|
+
async function openInEditor(filePath, config) {
|
|
70
|
+
try {
|
|
71
|
+
await execAsync(`"${config.editor}" "${filePath}"`);
|
|
72
|
+
} catch (ex) {
|
|
73
|
+
consola.warn(`Could not open in editor : '${config.editor}'. Modify your editor in the config: examples include 'code', 'code-insiders', etc...`, ex);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function todayCommand(config) {
|
|
77
|
+
try {
|
|
78
|
+
const fileInfo = generateJournalFileInfo();
|
|
79
|
+
const filePath = path__default.join(config.journalDir, ...fileInfo.pathPrefix, fileInfo.fileName);
|
|
80
|
+
ensureDirectoryExists(path__default.join(config.journalDir, ...fileInfo.pathPrefix));
|
|
81
|
+
if (!existsSync(filePath)) {
|
|
82
|
+
const content = createJournalContent({ mondayDate: fileInfo.mondayDate });
|
|
83
|
+
writeFileSync(filePath, content, "utf8");
|
|
84
|
+
consola.info(`Created new journal file: ${colors.cyan(filePath)}`);
|
|
85
|
+
} else {
|
|
86
|
+
consola.info(`Opening existing journal file: ${colors.cyan(filePath)}`);
|
|
87
|
+
}
|
|
88
|
+
await openInEditor(filePath, config);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
consola.error("Error creating journal file:", error);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function generateJournalFileInfo(date = /* @__PURE__ */ new Date()) {
|
|
95
|
+
const monday = getMondayOfWeek(new Date(date));
|
|
96
|
+
const fileName = `${formatDate(monday)}-week.md`;
|
|
97
|
+
const pathPrefix = [`${date.getFullYear()}`, "journal"];
|
|
98
|
+
return { pathPrefix, fileName, mondayDate: monday };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const constants = {
|
|
102
|
+
toolName: "towles-tool"
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
function printJson(obj) {
|
|
106
|
+
consola.log(util.inspect(obj, {
|
|
107
|
+
depth: 2,
|
|
108
|
+
colors: true,
|
|
109
|
+
showHidden: false,
|
|
110
|
+
compact: false
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
function printDebug(message, ...args) {
|
|
114
|
+
if (process.env.DEBUG) {
|
|
115
|
+
consola.log(`DEBUG: ${message}`, ...args);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getDefaultConfig() {
|
|
120
|
+
return {
|
|
121
|
+
journalDir: path.join(homedir(), "journal"),
|
|
122
|
+
editor: "code",
|
|
123
|
+
debug: false
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async function loadTowlesToolConfig({
|
|
127
|
+
cwd,
|
|
128
|
+
overrides
|
|
129
|
+
}) {
|
|
130
|
+
await setupDotenv({ cwd });
|
|
131
|
+
const defaults = getDefaultConfig();
|
|
132
|
+
const defaultConfigFolder = path.join(homedir(), ".config", constants.toolName);
|
|
133
|
+
const updateResult = await updateConfig({
|
|
134
|
+
cwd: defaultConfigFolder,
|
|
135
|
+
configFile: `${constants.toolName}.config`,
|
|
136
|
+
createExtension: ".ts",
|
|
137
|
+
async onCreate({ configFile: configFile2 }) {
|
|
138
|
+
const shallCreate = await consola.prompt(
|
|
139
|
+
`Do you want to initialize a new config in ${colors.cyan(configFile2)}?`,
|
|
140
|
+
{
|
|
141
|
+
type: "confirm",
|
|
142
|
+
default: true
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
if (shallCreate !== true) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
return `
|
|
149
|
+
// Default configuration for Towles Tool
|
|
150
|
+
// You can customize these values to fit your needs
|
|
151
|
+
// cwd: null means it will use the current working directory
|
|
152
|
+
export default ${JSON.stringify(defaults, null, 2)};
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
// async onUpdate(config) {
|
|
156
|
+
// consola.info(`Configuration updated in ${colors.cyan(path.relative('.', configFile))}`)
|
|
157
|
+
// return config
|
|
158
|
+
// },
|
|
159
|
+
}).catch((error) => {
|
|
160
|
+
consola.error(`Failed to update config: ${error.message}`);
|
|
161
|
+
return null;
|
|
162
|
+
});
|
|
163
|
+
if (!updateResult?.configFile) {
|
|
164
|
+
consola.error(`Failed to load or update config. Please check your configuration.`);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
const { config, configFile } = await loadConfig({
|
|
168
|
+
cwd: cwd || defaultConfigFolder,
|
|
169
|
+
configFile: updateResult.configFile,
|
|
170
|
+
name: constants.toolName,
|
|
171
|
+
packageJson: true,
|
|
172
|
+
defaults,
|
|
173
|
+
overrides: {
|
|
174
|
+
// cwd,
|
|
175
|
+
...overrides
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
printDebug(`Using config from: ${colors.cyan(configFile)}`);
|
|
179
|
+
return await resolveTowlesToolConfig(config, configFile, cwd);
|
|
180
|
+
}
|
|
181
|
+
async function resolveTowlesToolConfig(config, configFile, cwd) {
|
|
182
|
+
return {
|
|
183
|
+
configFile,
|
|
184
|
+
config,
|
|
185
|
+
cwd
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function main() {
|
|
190
|
+
const consola$1 = consola.withTag(constants.toolName);
|
|
191
|
+
const configWrapper = await loadTowlesToolConfig({ cwd: process.cwd() });
|
|
192
|
+
const program = new Command();
|
|
193
|
+
program.name(constants.toolName).description("One off quality of life scripts that I use on a daily basis").version(version);
|
|
194
|
+
program.command("today").description("Create and open a weekly journal file based on Monday of current week").action(async () => {
|
|
195
|
+
await todayCommand(configWrapper.config);
|
|
196
|
+
});
|
|
197
|
+
program.command("config").description("set or show configuration file.").action(async () => {
|
|
198
|
+
consola$1.log(colors.green("Showing configuration..."));
|
|
199
|
+
consola$1.log("Config File:", configWrapper.configFile);
|
|
200
|
+
printJson(configWrapper.config);
|
|
201
|
+
});
|
|
202
|
+
program.parse();
|
|
203
|
+
}
|
|
204
|
+
await main();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@towles/tool",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.7",
|
|
5
5
|
"description": "One off quality of life scripts that I use on a daily basis.",
|
|
6
6
|
"author": "Chris Towles <Chris.Towles.Dev@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"
|
|
36
|
+
"c12": "^3.0.4",
|
|
37
|
+
"commander": "^14.0.0",
|
|
38
|
+
"consola": "^3.4.2"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
41
|
"@antfu/eslint-config": "^4.10.1",
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
"bumpp": "^10.1.0",
|
|
44
46
|
"eslint": "^9.22.0",
|
|
45
47
|
"lint-staged": "^15.5.0",
|
|
48
|
+
"magicast": "^0.3.5",
|
|
46
49
|
"simple-git-hooks": "^2.11.1",
|
|
47
50
|
"tinyexec": "^0.3.2",
|
|
48
51
|
"tsx": "^4.19.3",
|