@xylabs/ts-scripts-yarn3 7.4.11 → 7.4.13

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.
@@ -192,18 +192,148 @@ var generateIgnoreFiles = (filename3, pkg) => {
192
192
  return succeeded ? 0 : 1;
193
193
  };
194
194
 
195
+ // src/lib/generateReadmeFiles.ts
196
+ import { execSync } from "child_process";
197
+ import FS from "fs";
198
+ import { readFile, writeFile } from "fs/promises";
199
+ import PATH2 from "path";
200
+ import chalk4 from "chalk";
201
+ function fillTemplate(template, data) {
202
+ const additionalData = { ...data, safeName: data.name.replaceAll("/", "__").replaceAll("@", "") };
203
+ return template.replaceAll(/\{\{(.*?)\}\}/g, (_, key) => additionalData[key.trim()] ?? "");
204
+ }
205
+ function generateTypedoc(packageLocation, entryPoints) {
206
+ const tempDir = PATH2.join(packageLocation, ".temp-typedoc");
207
+ try {
208
+ if (!FS.existsSync(tempDir)) {
209
+ FS.mkdirSync(tempDir, { recursive: true });
210
+ }
211
+ const typedocConfig = {
212
+ disableSources: true,
213
+ entryPointStrategy: "expand",
214
+ entryPoints: entryPoints.map((ep) => PATH2.resolve(packageLocation, ep)),
215
+ excludeExternals: true,
216
+ excludeInternal: true,
217
+ excludePrivate: true,
218
+ githubPages: false,
219
+ hideBreadcrumbs: true,
220
+ hideGenerator: true,
221
+ hidePageTitle: true,
222
+ out: tempDir,
223
+ plugin: ["typedoc-plugin-markdown"],
224
+ readme: "none",
225
+ skipErrorChecking: true,
226
+ sort: ["source-order"],
227
+ theme: "markdown",
228
+ useCodeBlocks: true
229
+ };
230
+ const typedocJsonPath = PATH2.join(tempDir, "typedoc.json");
231
+ FS.writeFileSync(typedocJsonPath, JSON.stringify(typedocConfig, null, 2));
232
+ try {
233
+ execSync(`npx typedoc --options ${typedocJsonPath}`, {
234
+ cwd: process.cwd(),
235
+ stdio: ["ignore", "pipe", "pipe"]
236
+ });
237
+ } catch {
238
+ return "";
239
+ }
240
+ return consolidateMarkdown(tempDir);
241
+ } catch {
242
+ return "";
243
+ } finally {
244
+ try {
245
+ FS.rmSync(tempDir, { force: true, recursive: true });
246
+ } catch {
247
+ }
248
+ }
249
+ }
250
+ function consolidateMarkdown(tempDir) {
251
+ let consolidated = "## Reference\n\n";
252
+ const mainReadmePath = PATH2.join(tempDir, "README.md");
253
+ if (FS.existsSync(mainReadmePath)) {
254
+ const mainContent = FS.readFileSync(mainReadmePath, "utf8").replace(/^---(.|\n)*?---\n/, "").replace(/^# .+\n/, "").replaceAll(/\]\((.+?)\.md\)/g, "](#$1)");
255
+ consolidated += mainContent + "\n\n";
256
+ }
257
+ consolidated += processDirectory(tempDir);
258
+ return consolidated.replaceAll(/\n\n\n+/g, "\n\n").replaceAll(/^#### /gm, "### ").replaceAll(/^##### /gm, "#### ").replaceAll(/^###### /gm, "##### ");
259
+ }
260
+ function processDirectory(dir, level = 0) {
261
+ const indent = " ".repeat(level);
262
+ let content = "";
263
+ try {
264
+ const items = FS.readdirSync(dir, { withFileTypes: true });
265
+ for (const item of items) {
266
+ if (item.isDirectory()) continue;
267
+ if (item.name === "README.md" || !item.name.endsWith(".md")) continue;
268
+ const fileContent = FS.readFileSync(PATH2.join(dir, item.name), "utf8").replace(/^---(.|\n)*?---\n/, "");
269
+ const moduleName = item.name.replace(".md", "");
270
+ content += `
271
+
272
+ ${indent}### <a id="${moduleName}"></a>${moduleName}
273
+
274
+ `;
275
+ content += fileContent.replace(/^# .+\n/, "").replaceAll(/\]\((.+?)\.md\)/g, "](#$1)");
276
+ }
277
+ for (const item of items) {
278
+ if (!item.isDirectory()) continue;
279
+ if (item.name === "spec" || item.name.includes(".spec")) continue;
280
+ content += `
281
+
282
+ ${indent}### ${item.name}
283
+ `;
284
+ content += processDirectory(PATH2.join(dir, item.name), level + 1);
285
+ }
286
+ } catch {
287
+ }
288
+ return content;
289
+ }
290
+ async function generateReadmeFiles({
291
+ pkg,
292
+ templatePath,
293
+ typedoc = false,
294
+ verbose
295
+ }) {
296
+ console.log(chalk4.green("Generate README Files"));
297
+ const cwd = INIT_CWD() ?? ".";
298
+ const resolvedTemplatePath = templatePath ?? PATH2.join(cwd, "scripts", "README.template.md");
299
+ let template;
300
+ try {
301
+ template = await readFile(resolvedTemplatePath, "utf8");
302
+ } catch {
303
+ console.error(chalk4.red(`Template not found: ${resolvedTemplatePath}`));
304
+ return 1;
305
+ }
306
+ const workspaces = pkg ? [yarnWorkspace(pkg)] : yarnWorkspaces();
307
+ let failed = false;
308
+ for (const { location, name } of workspaces) {
309
+ try {
310
+ const pkgJsonPath = PATH2.join(location, "package.json");
311
+ const pkgJson = JSON.parse(await readFile(pkgJsonPath, "utf8"));
312
+ const typedocContent = typedoc ? generateTypedoc(location, ["src/index*.ts"]) : "";
313
+ const readmeContent = fillTemplate(template, { ...pkgJson, typedoc: typedocContent });
314
+ await writeFile(PATH2.join(location, "README.md"), readmeContent);
315
+ if (verbose) console.log(chalk4.green(` ${name}`));
316
+ } catch (ex) {
317
+ const error = ex;
318
+ console.warn(chalk4.yellow(` Skipped ${location}: ${error.message}`));
319
+ failed = true;
320
+ }
321
+ }
322
+ return failed ? 1 : 0;
323
+ }
324
+
195
325
  // src/lib/runSteps.ts
196
326
  import { spawnSync as spawnSync3 } from "child_process";
197
327
  import { existsSync as existsSync2 } from "fs";
198
- import chalk4 from "chalk";
328
+ import chalk5 from "chalk";
199
329
  var runSteps = (name, steps, exitOnFail = true, messages) => {
200
330
  return safeExit(() => {
201
331
  const pkgName = process.env.npm_package_name;
202
- console.log(chalk4.green(`${name} [${pkgName}]`));
332
+ console.log(chalk5.green(`${name} [${pkgName}]`));
203
333
  let totalStatus = 0;
204
334
  for (const [i, [command, args, config]] of steps.entries()) {
205
335
  if (messages?.[i]) {
206
- console.log(chalk4.gray(messages?.[i]));
336
+ console.log(chalk5.gray(messages?.[i]));
207
337
  }
208
338
  const argList = Array.isArray(args) ? args : args.split(" ");
209
339
  if (command === "node" && !existsSync2(argList[0])) {
@@ -232,15 +362,15 @@ import {
232
362
  unlinkSync,
233
363
  writeFileSync as writeFileSync2
234
364
  } from "fs";
235
- import PATH2 from "path";
236
- import chalk5 from "chalk";
365
+ import PATH3 from "path";
366
+ import chalk6 from "chalk";
237
367
  var syncCommandFiles = (commandsDir) => {
238
368
  const templates = claudeCommandTemplates();
239
369
  const templateNames = new Set(Object.keys(templates));
240
370
  let updated = 0;
241
371
  let created = 0;
242
372
  for (const [filename3, content] of Object.entries(templates)) {
243
- const targetPath = PATH2.resolve(commandsDir, filename3);
373
+ const targetPath = PATH3.resolve(commandsDir, filename3);
244
374
  const existing = existsSync3(targetPath) ? readFileSync3(targetPath, "utf8") : void 0;
245
375
  if (existing === content) continue;
246
376
  writeFileSync2(targetPath, content, "utf8");
@@ -261,7 +391,7 @@ var removeStaleCommands = (commandsDir, templateNames) => {
261
391
  let removed = 0;
262
392
  for (const file of existingCommands) {
263
393
  if (!templateNames.has(file)) {
264
- unlinkSync(PATH2.resolve(commandsDir, file));
394
+ unlinkSync(PATH3.resolve(commandsDir, file));
265
395
  removed++;
266
396
  }
267
397
  }
@@ -274,14 +404,14 @@ var logCommandsResult = (created, updated, removed) => {
274
404
  updated ? `${updated} updated` : "",
275
405
  removed ? `${removed} removed` : ""
276
406
  ].filter(Boolean);
277
- console.log(chalk5.green(`.claude/commands/${XYLABS_COMMANDS_PREFIX}*.md: ${parts.join(", ")}`));
407
+ console.log(chalk6.green(`.claude/commands/${XYLABS_COMMANDS_PREFIX}*.md: ${parts.join(", ")}`));
278
408
  } else {
279
- console.log(chalk5.gray(`.claude/commands/${XYLABS_COMMANDS_PREFIX}*.md: already up to date`));
409
+ console.log(chalk6.gray(`.claude/commands/${XYLABS_COMMANDS_PREFIX}*.md: already up to date`));
280
410
  }
281
411
  };
282
412
  var claudeCommands = () => {
283
413
  const cwd = INIT_CWD() ?? process.cwd();
284
- const commandsDir = PATH2.resolve(cwd, ".claude", "commands");
414
+ const commandsDir = PATH3.resolve(cwd, ".claude", "commands");
285
415
  mkdirSync(commandsDir, { recursive: true });
286
416
  const {
287
417
  created,
@@ -302,15 +432,15 @@ import {
302
432
  unlinkSync as unlinkSync2,
303
433
  writeFileSync as writeFileSync3
304
434
  } from "fs";
305
- import PATH3 from "path";
306
- import chalk6 from "chalk";
435
+ import PATH4 from "path";
436
+ import chalk7 from "chalk";
307
437
  var syncRuleFiles = (rulesDir) => {
308
438
  const templates = claudeMdRuleTemplates();
309
439
  const templateNames = new Set(Object.keys(templates));
310
440
  let updated = 0;
311
441
  let created = 0;
312
442
  for (const [filename3, content] of Object.entries(templates)) {
313
- const targetPath = PATH3.resolve(rulesDir, filename3);
443
+ const targetPath = PATH4.resolve(rulesDir, filename3);
314
444
  const existing = existsSync4(targetPath) ? readFileSync4(targetPath, "utf8") : void 0;
315
445
  if (existing === content) continue;
316
446
  writeFileSync3(targetPath, content, "utf8");
@@ -331,7 +461,7 @@ var removeStaleRules = (rulesDir, templateNames) => {
331
461
  let removed = 0;
332
462
  for (const file of existingRules) {
333
463
  if (!templateNames.has(file)) {
334
- unlinkSync2(PATH3.resolve(rulesDir, file));
464
+ unlinkSync2(PATH4.resolve(rulesDir, file));
335
465
  removed++;
336
466
  }
337
467
  }
@@ -344,26 +474,26 @@ var logRulesResult = (created, updated, removed) => {
344
474
  updated ? `${updated} updated` : "",
345
475
  removed ? `${removed} removed` : ""
346
476
  ].filter(Boolean);
347
- console.log(chalk6.green(`.claude/rules/${XYLABS_RULES_PREFIX}*.md: ${parts.join(", ")}`));
477
+ console.log(chalk7.green(`.claude/rules/${XYLABS_RULES_PREFIX}*.md: ${parts.join(", ")}`));
348
478
  } else {
349
- console.log(chalk6.gray(`.claude/rules/${XYLABS_RULES_PREFIX}*.md: already up to date`));
479
+ console.log(chalk7.gray(`.claude/rules/${XYLABS_RULES_PREFIX}*.md: already up to date`));
350
480
  }
351
481
  };
352
482
  var ensureProjectClaudeMd = (cwd, force) => {
353
- const projectPath = PATH3.resolve(cwd, "CLAUDE.md");
483
+ const projectPath = PATH4.resolve(cwd, "CLAUDE.md");
354
484
  if (!existsSync4(projectPath) || force) {
355
485
  if (force && existsSync4(projectPath)) {
356
- console.log(chalk6.yellow("Overwriting existing CLAUDE.md"));
486
+ console.log(chalk7.yellow("Overwriting existing CLAUDE.md"));
357
487
  }
358
488
  writeFileSync3(projectPath, claudeMdProjectTemplate(), "utf8");
359
- console.log(chalk6.green("Generated CLAUDE.md"));
489
+ console.log(chalk7.green("Generated CLAUDE.md"));
360
490
  } else {
361
- console.log(chalk6.gray("CLAUDE.md already exists (skipped)"));
491
+ console.log(chalk7.gray("CLAUDE.md already exists (skipped)"));
362
492
  }
363
493
  };
364
494
  var claudeRules = ({ force } = {}) => {
365
495
  const cwd = INIT_CWD() ?? process.cwd();
366
- const rulesDir = PATH3.resolve(cwd, ".claude", "rules");
496
+ const rulesDir = PATH4.resolve(cwd, ".claude", "rules");
367
497
  mkdirSync2(rulesDir, { recursive: true });
368
498
  const {
369
499
  created,
@@ -378,10 +508,10 @@ var claudeRules = ({ force } = {}) => {
378
508
 
379
509
  // src/actions/clean-docs.ts
380
510
  import path from "path";
381
- import chalk7 from "chalk";
511
+ import chalk8 from "chalk";
382
512
  var cleanDocs = () => {
383
513
  const pkgName = process.env.npm_package_name;
384
- console.log(chalk7.green(`Cleaning Docs [${pkgName}]`));
514
+ console.log(chalk8.green(`Cleaning Docs [${pkgName}]`));
385
515
  for (const { location } of yarnWorkspaces()) deleteGlob(path.join(location, "docs"));
386
516
  return 0;
387
517
  };
@@ -410,7 +540,7 @@ var filename = ".gitignore";
410
540
  var gitignoreGen = (pkg) => generateIgnoreFiles(filename, pkg);
411
541
 
412
542
  // src/actions/gitlint.ts
413
- import chalk8 from "chalk";
543
+ import chalk9 from "chalk";
414
544
  import ParseGitConfig from "parse-git-config";
415
545
  var gitlint = () => {
416
546
  console.log(`
@@ -421,7 +551,7 @@ Gitlint Start [${process.cwd()}]
421
551
  const errors = 0;
422
552
  const gitConfig = ParseGitConfig.sync();
423
553
  const warn = (message) => {
424
- console.warn(chalk8.yellow(`Warning: ${message}`));
554
+ console.warn(chalk9.yellow(`Warning: ${message}`));
425
555
  warnings++;
426
556
  };
427
557
  if (gitConfig.core.ignorecase) {
@@ -441,13 +571,13 @@ Gitlint Start [${process.cwd()}]
441
571
  }
442
572
  const resultMessages = [];
443
573
  if (valid > 0) {
444
- resultMessages.push(chalk8.green(`Passed: ${valid}`));
574
+ resultMessages.push(chalk9.green(`Passed: ${valid}`));
445
575
  }
446
576
  if (warnings > 0) {
447
- resultMessages.push(chalk8.yellow(`Warnings: ${warnings}`));
577
+ resultMessages.push(chalk9.yellow(`Warnings: ${warnings}`));
448
578
  }
449
579
  if (errors > 0) {
450
- resultMessages.push(chalk8.red(` Errors: ${errors}`));
580
+ resultMessages.push(chalk9.red(` Errors: ${errors}`));
451
581
  }
452
582
  console.warn(`Gitlint Finish [ ${resultMessages.join(" | ")} ]
453
583
  `);
@@ -455,8 +585,8 @@ Gitlint Start [${process.cwd()}]
455
585
  };
456
586
 
457
587
  // src/actions/gitlint-fix.ts
458
- import { execSync } from "child_process";
459
- import chalk9 from "chalk";
588
+ import { execSync as execSync2 } from "child_process";
589
+ import chalk10 from "chalk";
460
590
  import ParseGitConfig2 from "parse-git-config";
461
591
  var gitlintFix = () => {
462
592
  console.log(`
@@ -464,22 +594,22 @@ Gitlint Fix Start [${process.cwd()}]
464
594
  `);
465
595
  const gitConfig = ParseGitConfig2.sync();
466
596
  if (gitConfig.core.ignorecase) {
467
- execSync("git config core.ignorecase false", { stdio: "inherit" });
468
- console.warn(chalk9.yellow("\nGitlint Fix: Updated core.ignorecase to be false\n"));
597
+ execSync2("git config core.ignorecase false", { stdio: "inherit" });
598
+ console.warn(chalk10.yellow("\nGitlint Fix: Updated core.ignorecase to be false\n"));
469
599
  }
470
600
  if (gitConfig.core.autocrlf !== false) {
471
- execSync("git config core.autocrlf false", { stdio: "inherit" });
472
- console.warn(chalk9.yellow("\nGitlint Fix: Updated core.autocrlf to be false\n"));
601
+ execSync2("git config core.autocrlf false", { stdio: "inherit" });
602
+ console.warn(chalk10.yellow("\nGitlint Fix: Updated core.autocrlf to be false\n"));
473
603
  }
474
604
  if (gitConfig.core.eol !== "lf") {
475
- execSync("git config core.eol lf", { stdio: "inherit" });
476
- console.warn(chalk9.yellow('\nGitlint Fix: Updated core.eol to be "lf"\n'));
605
+ execSync2("git config core.eol lf", { stdio: "inherit" });
606
+ console.warn(chalk10.yellow('\nGitlint Fix: Updated core.eol to be "lf"\n'));
477
607
  }
478
608
  return 1;
479
609
  };
480
610
 
481
611
  // src/actions/license.ts
482
- import chalk10 from "chalk";
612
+ import chalk11 from "chalk";
483
613
  import { init } from "license-checker";
484
614
  var license = async (pkg) => {
485
615
  const workspaces = yarnWorkspaces();
@@ -504,18 +634,18 @@ var license = async (pkg) => {
504
634
  "LGPL-3.0-or-later",
505
635
  "Python-2.0"
506
636
  ]);
507
- console.log(chalk10.green("License Checker"));
637
+ console.log(chalk11.green("License Checker"));
508
638
  return (await Promise.all(
509
639
  workspaceList.map(({ location, name }) => {
510
640
  return new Promise((resolve) => {
511
641
  init({ production: true, start: location }, (error, packages) => {
512
642
  if (error) {
513
- console.error(chalk10.red(`License Checker [${name}] Error`));
514
- console.error(chalk10.gray(error));
643
+ console.error(chalk11.red(`License Checker [${name}] Error`));
644
+ console.error(chalk11.gray(error));
515
645
  console.log("\n");
516
646
  resolve(1);
517
647
  } else {
518
- console.log(chalk10.green(`License Checker [${name}]`));
648
+ console.log(chalk11.green(`License Checker [${name}]`));
519
649
  let count = 0;
520
650
  for (const [name2, info] of Object.entries(packages)) {
521
651
  const licenses = Array.isArray(info.licenses) ? info.licenses : [info.licenses];
@@ -531,7 +661,7 @@ var license = async (pkg) => {
531
661
  }
532
662
  if (!orLicenseFound) {
533
663
  count++;
534
- console.warn(chalk10.yellow(`${name2}: Package License not allowed [${license2}]`));
664
+ console.warn(chalk11.yellow(`${name2}: Package License not allowed [${license2}]`));
535
665
  }
536
666
  }
537
667
  }
@@ -549,6 +679,21 @@ var license = async (pkg) => {
549
679
  var filename2 = ".npmignore";
550
680
  var npmignoreGen = (pkg) => generateIgnoreFiles(filename2, pkg);
551
681
 
682
+ // src/actions/readme-gen.ts
683
+ async function readmeGen({
684
+ pkg,
685
+ templatePath,
686
+ typedoc,
687
+ verbose
688
+ }) {
689
+ return await generateReadmeFiles({
690
+ pkg,
691
+ templatePath,
692
+ typedoc,
693
+ verbose
694
+ });
695
+ }
696
+
552
697
  // src/actions/retest.ts
553
698
  var retest = () => {
554
699
  return runSteps("Test", [
@@ -684,6 +829,29 @@ var xyCommonCommands = (args) => {
684
829
  if (argv.verbose) console.log("NpmIgnore Gen");
685
830
  process.exitCode = npmignoreGen();
686
831
  }
832
+ ).command(
833
+ "readme-gen [package]",
834
+ "Readme Gen - Generate README.md files from template",
835
+ (yargs) => {
836
+ return packagePositionalParam(yargs).option("template", {
837
+ alias: "t",
838
+ description: "Path to README.template.md",
839
+ type: "string"
840
+ }).option("typedoc", {
841
+ default: false,
842
+ description: "Generate TypeDoc reference sections",
843
+ type: "boolean"
844
+ });
845
+ },
846
+ async (argv) => {
847
+ if (argv.verbose) console.log("Readme Gen");
848
+ process.exitCode = await readmeGen({
849
+ pkg: argv.package,
850
+ templatePath: argv.template,
851
+ typedoc: argv.typedoc,
852
+ verbose: !!argv.verbose
853
+ });
854
+ }
687
855
  ).command(
688
856
  "retest",
689
857
  "Re-Test - Run Jest Tests with cleaned cache",