@md2do/cli 0.4.0 → 0.5.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.
- package/CHANGELOG.md +22 -0
- package/README.md +25 -0
- package/coverage/coverage-final.json +3 -2
- package/coverage/index.html +11 -11
- package/coverage/lcov-report/index.html +11 -11
- package/coverage/lcov-report/src/cli.ts.html +10 -4
- package/coverage/lcov-report/src/commands/config.ts.html +2269 -0
- package/coverage/lcov-report/src/commands/index.html +22 -7
- package/coverage/lcov-report/src/commands/index.ts.html +7 -4
- package/coverage/lcov-report/src/commands/list.ts.html +1 -1
- package/coverage/lcov-report/src/commands/stats.ts.html +1 -1
- package/coverage/lcov-report/src/commands/todoist.ts.html +1 -1
- package/coverage/lcov-report/src/formatters/index.html +1 -1
- package/coverage/lcov-report/src/formatters/json.ts.html +1 -1
- package/coverage/lcov-report/src/formatters/pretty.ts.html +1 -1
- package/coverage/lcov-report/src/index.html +5 -5
- package/coverage/lcov-report/src/index.ts.html +1 -1
- package/coverage/lcov-report/src/scanner.ts.html +1 -1
- package/coverage/lcov.info +746 -3
- package/coverage/src/cli.ts.html +10 -4
- package/coverage/src/commands/config.ts.html +2269 -0
- package/coverage/src/commands/index.html +22 -7
- package/coverage/src/commands/index.ts.html +7 -4
- package/coverage/src/commands/list.ts.html +1 -1
- package/coverage/src/commands/stats.ts.html +1 -1
- package/coverage/src/commands/todoist.ts.html +1 -1
- package/coverage/src/formatters/index.html +1 -1
- package/coverage/src/formatters/json.ts.html +1 -1
- package/coverage/src/formatters/pretty.ts.html +1 -1
- package/coverage/src/index.html +5 -5
- package/coverage/src/index.ts.html +1 -1
- package/coverage/src/scanner.ts.html +1 -1
- package/dist/cli.js +466 -6
- package/dist/index.d.ts +6 -1
- package/dist/index.js +461 -0
- package/package.json +5 -2
- package/src/cli.ts +2 -0
- package/src/commands/config.ts +731 -0
- package/src/commands/index.ts +1 -0
package/dist/cli.js
CHANGED
|
@@ -24,9 +24,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
var
|
|
27
|
+
var import_commander5 = require("commander");
|
|
28
|
+
var import_fs2 = require("fs");
|
|
29
|
+
var import_path2 = require("path");
|
|
30
30
|
|
|
31
31
|
// src/commands/list.ts
|
|
32
32
|
var import_commander = require("commander");
|
|
@@ -1202,21 +1202,481 @@ async function todoistSyncAction(options) {
|
|
|
1202
1202
|
console.log("");
|
|
1203
1203
|
}
|
|
1204
1204
|
|
|
1205
|
+
// src/commands/config.ts
|
|
1206
|
+
var import_commander4 = require("commander");
|
|
1207
|
+
var import_config3 = require("@md2do/config");
|
|
1208
|
+
var import_fs = require("fs");
|
|
1209
|
+
var import_path = require("path");
|
|
1210
|
+
var import_os = require("os");
|
|
1211
|
+
var import_child_process = require("child_process");
|
|
1212
|
+
var import_js_yaml = __toESM(require("js-yaml"));
|
|
1213
|
+
function createConfigCommand() {
|
|
1214
|
+
const command = new import_commander4.Command("config");
|
|
1215
|
+
command.description("Manage md2do configuration");
|
|
1216
|
+
command.addCommand(createConfigInitCommand());
|
|
1217
|
+
command.addCommand(createConfigSetCommand());
|
|
1218
|
+
command.addCommand(createConfigGetCommand());
|
|
1219
|
+
command.addCommand(createConfigListCommand());
|
|
1220
|
+
command.addCommand(createConfigEditCommand());
|
|
1221
|
+
command.addCommand(createConfigValidateCommand());
|
|
1222
|
+
return command;
|
|
1223
|
+
}
|
|
1224
|
+
function createConfigInitCommand() {
|
|
1225
|
+
const command = new import_commander4.Command("init");
|
|
1226
|
+
command.description("Initialize md2do configuration with interactive prompts").option("-g, --global", "Create global configuration in home directory").option(
|
|
1227
|
+
"--format <type>",
|
|
1228
|
+
"Config file format (json|yaml|js)",
|
|
1229
|
+
"json"
|
|
1230
|
+
).option("--default-assignee <username>", "Default assignee username").option("--workday-start <time>", "Work day start time (HH:MM)").option("--workday-end <time>", "Work day end time (HH:MM)").option(
|
|
1231
|
+
"--default-due-time <when>",
|
|
1232
|
+
"Default due time (start|end)",
|
|
1233
|
+
"end"
|
|
1234
|
+
).option(
|
|
1235
|
+
"--output-format <type>",
|
|
1236
|
+
"Output format (pretty|table|json)",
|
|
1237
|
+
"pretty"
|
|
1238
|
+
).option("--no-colors", "Disable colored output").option(
|
|
1239
|
+
"--warnings <level>",
|
|
1240
|
+
"Warning level (recommended|strict|off)",
|
|
1241
|
+
"recommended"
|
|
1242
|
+
).action(async (options) => {
|
|
1243
|
+
try {
|
|
1244
|
+
await configInitAction(options);
|
|
1245
|
+
} catch (error) {
|
|
1246
|
+
if (error instanceof Error && error.message === "canceled") {
|
|
1247
|
+
const p = await import("@clack/prompts");
|
|
1248
|
+
p.cancel("Configuration canceled");
|
|
1249
|
+
process.exit(0);
|
|
1250
|
+
}
|
|
1251
|
+
console.error(
|
|
1252
|
+
"Error:",
|
|
1253
|
+
error instanceof Error ? error.message : String(error)
|
|
1254
|
+
);
|
|
1255
|
+
process.exit(1);
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1258
|
+
return command;
|
|
1259
|
+
}
|
|
1260
|
+
async function configInitAction(options) {
|
|
1261
|
+
const p = await import("@clack/prompts");
|
|
1262
|
+
p.intro("Welcome to md2do configuration!");
|
|
1263
|
+
const hasAnyOption = options.defaultAssignee !== void 0 || options.workdayStart !== void 0 || options.workdayEnd !== void 0 || options.defaultDueTime !== void 0 || options.outputFormat !== void 0 || options.colors !== void 0 || options.warnings !== void 0;
|
|
1264
|
+
const interactive = !hasAnyOption;
|
|
1265
|
+
const config = {};
|
|
1266
|
+
if (interactive) {
|
|
1267
|
+
const defaultAssignee = await p.text({
|
|
1268
|
+
message: "Your username (for filtering tasks):",
|
|
1269
|
+
placeholder: "Leave empty to skip",
|
|
1270
|
+
validate: (value) => {
|
|
1271
|
+
if (value && !/^[a-zA-Z0-9_-]+$/.test(value)) {
|
|
1272
|
+
return "Username should only contain letters, numbers, dashes, and underscores";
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
const workdayStart = await p.text({
|
|
1277
|
+
message: "Work day start time (HH:MM):",
|
|
1278
|
+
initialValue: "08:00",
|
|
1279
|
+
validate: (value) => {
|
|
1280
|
+
if (typeof value === "string" && !/^\d{2}:\d{2}$/.test(value)) {
|
|
1281
|
+
return "Time must be in HH:MM format";
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
const workdayEnd = await p.text({
|
|
1286
|
+
message: "Work day end time (HH:MM):",
|
|
1287
|
+
initialValue: "17:00",
|
|
1288
|
+
validate: (value) => {
|
|
1289
|
+
if (typeof value === "string" && !/^\d{2}:\d{2}$/.test(value)) {
|
|
1290
|
+
return "Time must be in HH:MM format";
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1294
|
+
const defaultDueTime = await p.select({
|
|
1295
|
+
message: "Default due time:",
|
|
1296
|
+
options: [
|
|
1297
|
+
{ value: "end", label: "End of day" },
|
|
1298
|
+
{ value: "start", label: "Start of day" }
|
|
1299
|
+
],
|
|
1300
|
+
initialValue: "end"
|
|
1301
|
+
});
|
|
1302
|
+
const outputFormat = await p.select({
|
|
1303
|
+
message: "Output format:",
|
|
1304
|
+
options: [
|
|
1305
|
+
{ value: "pretty", label: "Pretty (human-readable)" },
|
|
1306
|
+
{ value: "table", label: "Table (structured)" },
|
|
1307
|
+
{ value: "json", label: "JSON (machine-readable)" }
|
|
1308
|
+
],
|
|
1309
|
+
initialValue: "pretty"
|
|
1310
|
+
});
|
|
1311
|
+
const colors = await p.confirm({
|
|
1312
|
+
message: "Enable colored output?",
|
|
1313
|
+
initialValue: true
|
|
1314
|
+
});
|
|
1315
|
+
const warnings = await p.select({
|
|
1316
|
+
message: "Warning level:",
|
|
1317
|
+
options: [
|
|
1318
|
+
{
|
|
1319
|
+
value: "recommended",
|
|
1320
|
+
label: "Recommended (validates format, metadata optional)"
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
value: "strict",
|
|
1324
|
+
label: "Strict (enforces complete metadata)"
|
|
1325
|
+
},
|
|
1326
|
+
{ value: "off", label: "Off (no warnings)" }
|
|
1327
|
+
],
|
|
1328
|
+
initialValue: "recommended"
|
|
1329
|
+
});
|
|
1330
|
+
if (defaultAssignee && typeof defaultAssignee === "string") {
|
|
1331
|
+
config.defaultAssignee = defaultAssignee;
|
|
1332
|
+
}
|
|
1333
|
+
config.workday = {
|
|
1334
|
+
startTime: typeof workdayStart === "string" ? workdayStart : "08:00",
|
|
1335
|
+
endTime: typeof workdayEnd === "string" ? workdayEnd : "17:00",
|
|
1336
|
+
defaultDueTime: typeof defaultDueTime === "string" ? defaultDueTime : "end"
|
|
1337
|
+
};
|
|
1338
|
+
config.output = {
|
|
1339
|
+
format: typeof outputFormat === "string" ? outputFormat : "pretty",
|
|
1340
|
+
colors: typeof colors === "boolean" ? colors : true,
|
|
1341
|
+
paths: true
|
|
1342
|
+
};
|
|
1343
|
+
if (typeof warnings === "string" && warnings === "off") {
|
|
1344
|
+
config.warnings = { enabled: false };
|
|
1345
|
+
} else if (typeof warnings === "string" && warnings === "strict") {
|
|
1346
|
+
config.warnings = {
|
|
1347
|
+
enabled: true,
|
|
1348
|
+
rules: {
|
|
1349
|
+
"unsupported-bullet": "warn",
|
|
1350
|
+
"malformed-checkbox": "warn",
|
|
1351
|
+
"missing-space-after": "warn",
|
|
1352
|
+
"missing-space-before": "warn",
|
|
1353
|
+
"relative-date-no-context": "warn",
|
|
1354
|
+
"missing-due-date": "warn",
|
|
1355
|
+
"missing-completed-date": "warn",
|
|
1356
|
+
"duplicate-todoist-id": "error",
|
|
1357
|
+
"file-read-error": "error"
|
|
1358
|
+
}
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
} else {
|
|
1362
|
+
if (options.defaultAssignee) {
|
|
1363
|
+
config.defaultAssignee = options.defaultAssignee;
|
|
1364
|
+
}
|
|
1365
|
+
config.workday = {
|
|
1366
|
+
startTime: options.workdayStart || "08:00",
|
|
1367
|
+
endTime: options.workdayEnd || "17:00",
|
|
1368
|
+
defaultDueTime: options.defaultDueTime || "end"
|
|
1369
|
+
};
|
|
1370
|
+
config.output = {
|
|
1371
|
+
format: options.outputFormat || "pretty",
|
|
1372
|
+
colors: options.colors ?? true,
|
|
1373
|
+
paths: true
|
|
1374
|
+
};
|
|
1375
|
+
if (options.warnings === "off") {
|
|
1376
|
+
config.warnings = { enabled: false };
|
|
1377
|
+
} else if (options.warnings === "strict") {
|
|
1378
|
+
config.warnings = {
|
|
1379
|
+
enabled: true,
|
|
1380
|
+
rules: {
|
|
1381
|
+
"unsupported-bullet": "warn",
|
|
1382
|
+
"malformed-checkbox": "warn",
|
|
1383
|
+
"missing-space-after": "warn",
|
|
1384
|
+
"missing-space-before": "warn",
|
|
1385
|
+
"relative-date-no-context": "warn",
|
|
1386
|
+
"missing-due-date": "warn",
|
|
1387
|
+
"missing-completed-date": "warn",
|
|
1388
|
+
"duplicate-todoist-id": "error",
|
|
1389
|
+
"file-read-error": "error"
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
try {
|
|
1395
|
+
(0, import_config3.validateConfig)(config);
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
p.cancel(
|
|
1398
|
+
`Invalid configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
1399
|
+
);
|
|
1400
|
+
process.exit(1);
|
|
1401
|
+
}
|
|
1402
|
+
const format = options.format || "json";
|
|
1403
|
+
const configPath = getConfigPath(options.global || false, format);
|
|
1404
|
+
if ((0, import_fs.existsSync)(configPath)) {
|
|
1405
|
+
if (interactive) {
|
|
1406
|
+
const overwrite = await p.confirm({
|
|
1407
|
+
message: `Configuration file already exists at ${configPath}. Overwrite?`,
|
|
1408
|
+
initialValue: false
|
|
1409
|
+
});
|
|
1410
|
+
if (!overwrite) {
|
|
1411
|
+
p.cancel("Configuration canceled");
|
|
1412
|
+
process.exit(0);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
writeConfigFile(configPath, config, format);
|
|
1417
|
+
p.outro(`\u2713 Configuration saved to ${configPath}`);
|
|
1418
|
+
}
|
|
1419
|
+
function createConfigSetCommand() {
|
|
1420
|
+
const command = new import_commander4.Command("set");
|
|
1421
|
+
command.description("Set a configuration value").argument("<key>", "Configuration key (e.g., workday.startTime)").argument("<value>", "Configuration value").option("-g, --global", "Set in global configuration").action((key, value, options) => {
|
|
1422
|
+
try {
|
|
1423
|
+
configSetAction(key, value, options);
|
|
1424
|
+
} catch (error) {
|
|
1425
|
+
console.error(
|
|
1426
|
+
"Error:",
|
|
1427
|
+
error instanceof Error ? error.message : String(error)
|
|
1428
|
+
);
|
|
1429
|
+
process.exit(1);
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
return command;
|
|
1433
|
+
}
|
|
1434
|
+
function configSetAction(key, value, options) {
|
|
1435
|
+
const isGlobal = options.global || false;
|
|
1436
|
+
const configPath = findExistingConfigPath(isGlobal);
|
|
1437
|
+
let config = {};
|
|
1438
|
+
let format = "json";
|
|
1439
|
+
if (configPath) {
|
|
1440
|
+
format = getConfigFormat(configPath);
|
|
1441
|
+
const content = (0, import_fs.readFileSync)(configPath, "utf-8");
|
|
1442
|
+
config = parseConfigFile(content, format);
|
|
1443
|
+
} else {
|
|
1444
|
+
format = "json";
|
|
1445
|
+
}
|
|
1446
|
+
const parsedValue = parseValue(value);
|
|
1447
|
+
setNestedValue(config, key, parsedValue);
|
|
1448
|
+
try {
|
|
1449
|
+
(0, import_config3.validateConfig)(config);
|
|
1450
|
+
} catch (error) {
|
|
1451
|
+
console.error(
|
|
1452
|
+
`Invalid configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
1453
|
+
);
|
|
1454
|
+
process.exit(1);
|
|
1455
|
+
}
|
|
1456
|
+
const finalPath = configPath || getConfigPath(isGlobal, format);
|
|
1457
|
+
writeConfigFile(finalPath, config, format);
|
|
1458
|
+
console.log(`\u2713 Set ${key} = ${value} in ${finalPath}`);
|
|
1459
|
+
}
|
|
1460
|
+
function createConfigGetCommand() {
|
|
1461
|
+
const command = new import_commander4.Command("get");
|
|
1462
|
+
command.description("Get a configuration value").argument("<key>", "Configuration key (e.g., workday.startTime)").option("-g, --global", "Get from global configuration only").action(async (key, options) => {
|
|
1463
|
+
try {
|
|
1464
|
+
await configGetAction(key, options);
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
console.error(
|
|
1467
|
+
"Error:",
|
|
1468
|
+
error instanceof Error ? error.message : String(error)
|
|
1469
|
+
);
|
|
1470
|
+
process.exit(1);
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
return command;
|
|
1474
|
+
}
|
|
1475
|
+
async function configGetAction(key, options) {
|
|
1476
|
+
const config = options.global ? await (0, import_config3.loadConfig)({ loadGlobal: true, loadEnv: false, cwd: (0, import_os.homedir)() }) : await (0, import_config3.loadConfig)();
|
|
1477
|
+
const value = getNestedValue(config, key);
|
|
1478
|
+
if (value === void 0) {
|
|
1479
|
+
console.log("(not set)");
|
|
1480
|
+
} else if (typeof value === "object") {
|
|
1481
|
+
console.log(JSON.stringify(value, null, 2));
|
|
1482
|
+
} else {
|
|
1483
|
+
console.log(value);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
function createConfigListCommand() {
|
|
1487
|
+
const command = new import_commander4.Command("list");
|
|
1488
|
+
command.description("Show all configuration values").option("--show-origin", "Show where each value comes from").action(async (options) => {
|
|
1489
|
+
try {
|
|
1490
|
+
await configListAction(options);
|
|
1491
|
+
} catch (error) {
|
|
1492
|
+
console.error(
|
|
1493
|
+
"Error:",
|
|
1494
|
+
error instanceof Error ? error.message : String(error)
|
|
1495
|
+
);
|
|
1496
|
+
process.exit(1);
|
|
1497
|
+
}
|
|
1498
|
+
});
|
|
1499
|
+
return command;
|
|
1500
|
+
}
|
|
1501
|
+
async function configListAction(options) {
|
|
1502
|
+
const config = await (0, import_config3.loadConfig)();
|
|
1503
|
+
console.log("");
|
|
1504
|
+
console.log("Current configuration:");
|
|
1505
|
+
console.log("");
|
|
1506
|
+
console.log(JSON.stringify(config, null, 2));
|
|
1507
|
+
console.log("");
|
|
1508
|
+
if (options.showOrigin) {
|
|
1509
|
+
console.log("Configuration sources:");
|
|
1510
|
+
console.log(" 1. Default values (built-in)");
|
|
1511
|
+
console.log(` 2. Global config (${getConfigPath(true, "json")})`);
|
|
1512
|
+
console.log(` 3. Project config (${getConfigPath(false, "json")})`);
|
|
1513
|
+
console.log(" 4. Environment variables");
|
|
1514
|
+
console.log("");
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
function createConfigEditCommand() {
|
|
1518
|
+
const command = new import_commander4.Command("edit");
|
|
1519
|
+
command.description("Open configuration file in your default editor").option("-g, --global", "Edit global configuration").action((options) => {
|
|
1520
|
+
try {
|
|
1521
|
+
configEditAction(options);
|
|
1522
|
+
} catch (error) {
|
|
1523
|
+
console.error(
|
|
1524
|
+
"Error:",
|
|
1525
|
+
error instanceof Error ? error.message : String(error)
|
|
1526
|
+
);
|
|
1527
|
+
process.exit(1);
|
|
1528
|
+
}
|
|
1529
|
+
});
|
|
1530
|
+
return command;
|
|
1531
|
+
}
|
|
1532
|
+
function configEditAction(options) {
|
|
1533
|
+
const isGlobal = options.global || false;
|
|
1534
|
+
let configPath = findExistingConfigPath(isGlobal);
|
|
1535
|
+
if (!configPath) {
|
|
1536
|
+
configPath = getConfigPath(isGlobal, "json");
|
|
1537
|
+
writeConfigFile(configPath, {}, "json");
|
|
1538
|
+
console.log(`Created new configuration file: ${configPath}`);
|
|
1539
|
+
}
|
|
1540
|
+
const editor = process.env.VISUAL || process.env.EDITOR || (process.platform === "win32" ? "notepad" : "vi");
|
|
1541
|
+
console.log(`Opening ${configPath} in ${editor}...`);
|
|
1542
|
+
try {
|
|
1543
|
+
(0, import_child_process.execSync)(`${editor} '${configPath}'`, { stdio: "inherit" });
|
|
1544
|
+
} catch (error) {
|
|
1545
|
+
console.error("Failed to open editor");
|
|
1546
|
+
console.error(`You can manually edit the file at: ${configPath}`);
|
|
1547
|
+
process.exit(1);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
function createConfigValidateCommand() {
|
|
1551
|
+
const command = new import_commander4.Command("validate");
|
|
1552
|
+
command.description("Validate current configuration").action(async () => {
|
|
1553
|
+
try {
|
|
1554
|
+
await configValidateAction();
|
|
1555
|
+
} catch (error) {
|
|
1556
|
+
console.error(
|
|
1557
|
+
"Error:",
|
|
1558
|
+
error instanceof Error ? error.message : String(error)
|
|
1559
|
+
);
|
|
1560
|
+
process.exit(1);
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
return command;
|
|
1564
|
+
}
|
|
1565
|
+
async function configValidateAction() {
|
|
1566
|
+
try {
|
|
1567
|
+
const config = await (0, import_config3.loadConfig)();
|
|
1568
|
+
(0, import_config3.validateConfig)(config);
|
|
1569
|
+
console.log("\u2713 Configuration is valid");
|
|
1570
|
+
} catch (error) {
|
|
1571
|
+
console.error(
|
|
1572
|
+
`Invalid configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
1573
|
+
);
|
|
1574
|
+
process.exit(1);
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
function getConfigPath(isGlobal, format) {
|
|
1578
|
+
const base = isGlobal ? (0, import_os.homedir)() : process.cwd();
|
|
1579
|
+
const fileName = format === "json" ? ".md2do.json" : format === "yaml" ? ".md2do.yaml" : ".md2do.js";
|
|
1580
|
+
return (0, import_path.join)(base, fileName);
|
|
1581
|
+
}
|
|
1582
|
+
function findExistingConfigPath(isGlobal) {
|
|
1583
|
+
const base = isGlobal ? (0, import_os.homedir)() : process.cwd();
|
|
1584
|
+
const possibleFiles = [
|
|
1585
|
+
".md2do.json",
|
|
1586
|
+
".md2do.yaml",
|
|
1587
|
+
".md2do.yml",
|
|
1588
|
+
".md2do.js",
|
|
1589
|
+
".md2do.cjs",
|
|
1590
|
+
"md2do.config.js",
|
|
1591
|
+
"md2do.config.cjs"
|
|
1592
|
+
];
|
|
1593
|
+
for (const file of possibleFiles) {
|
|
1594
|
+
const path = (0, import_path.join)(base, file);
|
|
1595
|
+
if ((0, import_fs.existsSync)(path)) {
|
|
1596
|
+
return path;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
return null;
|
|
1600
|
+
}
|
|
1601
|
+
function getConfigFormat(path) {
|
|
1602
|
+
if (path.endsWith(".json")) return "json";
|
|
1603
|
+
if (path.endsWith(".yaml") || path.endsWith(".yml")) return "yaml";
|
|
1604
|
+
return "js";
|
|
1605
|
+
}
|
|
1606
|
+
function parseConfigFile(content, format) {
|
|
1607
|
+
if (format === "json") {
|
|
1608
|
+
return JSON.parse(content);
|
|
1609
|
+
} else if (format === "yaml") {
|
|
1610
|
+
const loaded = import_js_yaml.default.load(content);
|
|
1611
|
+
return loaded || {};
|
|
1612
|
+
} else {
|
|
1613
|
+
return JSON.parse(content);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
function writeConfigFile(path, config, format) {
|
|
1617
|
+
let content;
|
|
1618
|
+
if (format === "json") {
|
|
1619
|
+
content = JSON.stringify(config, null, 2) + "\n";
|
|
1620
|
+
} else if (format === "yaml") {
|
|
1621
|
+
content = import_js_yaml.default.dump(config);
|
|
1622
|
+
} else {
|
|
1623
|
+
content = `module.exports = ${JSON.stringify(config, null, 2)};
|
|
1624
|
+
`;
|
|
1625
|
+
}
|
|
1626
|
+
(0, import_fs.writeFileSync)(path, content, "utf-8");
|
|
1627
|
+
}
|
|
1628
|
+
function parseValue(value) {
|
|
1629
|
+
if (value === "true") return true;
|
|
1630
|
+
if (value === "false") return false;
|
|
1631
|
+
const num = Number(value);
|
|
1632
|
+
if (!isNaN(num)) return num;
|
|
1633
|
+
try {
|
|
1634
|
+
return JSON.parse(value);
|
|
1635
|
+
} catch {
|
|
1636
|
+
return value;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
function getNestedValue(obj, path) {
|
|
1640
|
+
const keys = path.split(".");
|
|
1641
|
+
let current = obj;
|
|
1642
|
+
for (const key of keys) {
|
|
1643
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
1644
|
+
return void 0;
|
|
1645
|
+
}
|
|
1646
|
+
current = current[key];
|
|
1647
|
+
}
|
|
1648
|
+
return current;
|
|
1649
|
+
}
|
|
1650
|
+
function setNestedValue(obj, path, value) {
|
|
1651
|
+
const keys = path.split(".");
|
|
1652
|
+
const lastKey = keys.pop();
|
|
1653
|
+
if (!lastKey) return;
|
|
1654
|
+
let current = obj;
|
|
1655
|
+
for (const key of keys) {
|
|
1656
|
+
if (!(key in current) || typeof current[key] !== "object") {
|
|
1657
|
+
current[key] = {};
|
|
1658
|
+
}
|
|
1659
|
+
current = current[key];
|
|
1660
|
+
}
|
|
1661
|
+
current[lastKey] = value;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1205
1664
|
// src/cli.ts
|
|
1206
1665
|
var getVersion = () => {
|
|
1207
1666
|
try {
|
|
1208
|
-
const packagePath = (0,
|
|
1209
|
-
const packageJson = JSON.parse((0,
|
|
1667
|
+
const packagePath = (0, import_path2.join)(__dirname, "../package.json");
|
|
1668
|
+
const packageJson = JSON.parse((0, import_fs2.readFileSync)(packagePath, "utf-8"));
|
|
1210
1669
|
return packageJson.version;
|
|
1211
1670
|
} catch {
|
|
1212
1671
|
return "0.0.0";
|
|
1213
1672
|
}
|
|
1214
1673
|
};
|
|
1215
|
-
var program = new
|
|
1674
|
+
var program = new import_commander5.Command();
|
|
1216
1675
|
program.name("md2do").description("Scan and manage TODOs in markdown files").version(getVersion());
|
|
1217
1676
|
program.addCommand(createListCommand());
|
|
1218
1677
|
program.addCommand(createStatsCommand());
|
|
1219
1678
|
program.addCommand(createTodoistCommand());
|
|
1679
|
+
program.addCommand(createConfigCommand());
|
|
1220
1680
|
if (process.argv.length === 2) {
|
|
1221
1681
|
program.help();
|
|
1222
1682
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,4 +9,9 @@ declare function createStatsCommand(): Command;
|
|
|
9
9
|
*/
|
|
10
10
|
declare function createTodoistCommand(): Command;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Create the config command group
|
|
14
|
+
*/
|
|
15
|
+
declare function createConfigCommand(): Command;
|
|
16
|
+
|
|
17
|
+
export { createConfigCommand, createListCommand, createStatsCommand, createTodoistCommand };
|