@jpillora/take 0.11.0 → 0.12.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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/take.d.mts +1 -0
  3. package/take.mjs +71 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jpillora/take",
3
- "version": "0.11.0",
3
+ "version": "0.12.2",
4
4
  "description": "A minimal CLI library for building TypeScript-based command-line tools",
5
5
  "type": "module",
6
6
  "main": "./take.mjs",
package/take.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type SpawnOptions as nodeSpawnOptions } from "node:child_process";
2
+ export declare function insertHelp(path: string): void;
2
3
  export type Flag = {
3
4
  initial: number | string | boolean | Date;
4
5
  description: string;
package/take.mjs CHANGED
@@ -3,10 +3,20 @@
3
3
  // IMPORTANT: All code must stay in 1 file.
4
4
  // deno-lint-ignore-file no-explicit-any
5
5
  import { Buffer } from "node:buffer";
6
- import { readFile } from "node:fs/promises";
7
- import { basename } from "node:path";
6
+ import { readFile, writeFile } from "node:fs/promises";
7
+ import { basename, dirname, isAbsolute, join } from "node:path";
8
8
  import { spawn as nodeSpawn, } from "node:child_process";
9
9
  import process from "node:process";
10
+ let _insertHelpPath = null;
11
+ export function insertHelp(path) {
12
+ if (isAbsolute(path)) {
13
+ _insertHelpPath = path;
14
+ }
15
+ else {
16
+ const scriptDir = dirname(process.argv[1] || ".");
17
+ _insertHelpPath = join(scriptDir, path);
18
+ }
19
+ }
10
20
  export function newFlags(flags) {
11
21
  return flags;
12
22
  }
@@ -193,6 +203,64 @@ async function loadEnvFile(path) {
193
203
  return false;
194
204
  }
195
205
  }
206
+ const MARKER_START = "<!-- take:start -->";
207
+ const MARKER_END = "<!-- take:end -->";
208
+ async function _writeInsertHelp(commands) {
209
+ if (!_insertHelpPath)
210
+ return;
211
+ const path = _insertHelpPath;
212
+ // Build markdown list with flags as sub-bullets
213
+ const lines = [];
214
+ for (const cmd of commands) {
215
+ if (cmd.name === "debug")
216
+ continue;
217
+ const desc = cmd.description ? ` - ${cmd.description}` : "";
218
+ lines.push(`- \`${cmd.name}\`${desc}`);
219
+ // Add flags as sub-bullets (sorted, matching the CLI --help output, so the
220
+ // generated markdown is deterministic regardless of flag insertion order)
221
+ const shorts = new Set();
222
+ for (const flag of namedFlags(cmd.flags)) {
223
+ const { name } = flag;
224
+ const letter = name[0];
225
+ const shortStr = shorts.has(letter) ? "" : ` \`-${letter}\``;
226
+ shorts.add(letter);
227
+ const typeStr = typeof flag.initial === "boolean"
228
+ ? ""
229
+ : ` <${typeof flag.initial}>`;
230
+ const parts = [];
231
+ if (flag.env)
232
+ parts.push(`env=${flag.env}`);
233
+ if (flag.initial)
234
+ parts.push(`default=${flag.initial}`);
235
+ const extras = parts.length ? ` (${parts.join(" ")})` : "";
236
+ lines.push(` - \`--${name}\`${shortStr}${typeStr} - ${flag.description}${extras}`);
237
+ }
238
+ }
239
+ const content = MARKER_START + "\n" + lines.join("\n") + "\n" + MARKER_END;
240
+ // Read existing file
241
+ let fileContent;
242
+ try {
243
+ fileContent = await readFile(path, "utf-8");
244
+ }
245
+ catch {
246
+ return; // file doesn't exist, nothing to insert into
247
+ }
248
+ // Find markers and replace or append
249
+ const startIdx = fileContent.indexOf(MARKER_START);
250
+ const endIdx = fileContent.indexOf(MARKER_END);
251
+ let newContent;
252
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
253
+ newContent = fileContent.substring(0, startIdx) + content +
254
+ fileContent.substring(endIdx + MARKER_END.length);
255
+ }
256
+ else {
257
+ const sep = fileContent.endsWith("\n") ? "\n" : "\n\n";
258
+ newContent = fileContent + sep + content + "\n";
259
+ }
260
+ if (newContent !== fileContent) {
261
+ await writeFile(path, newContent, "utf-8");
262
+ }
263
+ }
196
264
  export async function Register(...commands) {
197
265
  // Load .env by default
198
266
  await loadEnvFile(".env");
@@ -238,6 +306,7 @@ export async function Register(...commands) {
238
306
  }
239
307
  }
240
308
  commands.sort((a, b) => (a.name < b.name ? -1 : 1));
309
+ await _writeInsertHelp(commands);
241
310
  const joinColumns = (table) => {
242
311
  const max = table.reduce((m, { left }) => Math.max(m, left.length), 0);
243
312
  return table