@xylabs/ts-scripts-yarn3 7.4.18 → 7.4.20
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.body.md +86 -0
- package/README.md +108 -0
- package/dist/actions/claude-commands.mjs +6 -2
- package/dist/actions/claude-commands.mjs.map +1 -1
- package/dist/actions/claude-rules.mjs +6 -2
- package/dist/actions/claude-rules.mjs.map +1 -1
- package/dist/actions/claude-skills.mjs +120 -0
- package/dist/actions/claude-skills.mjs.map +1 -0
- package/dist/actions/compile.mjs.map +1 -1
- package/dist/actions/cycle.mjs.map +1 -1
- package/dist/actions/dead.mjs.map +1 -1
- package/dist/actions/deploy-major.mjs.map +1 -1
- package/dist/actions/deploy-minor.mjs.map +1 -1
- package/dist/actions/deploy-next.mjs.map +1 -1
- package/dist/actions/deploy.mjs.map +1 -1
- package/dist/actions/fix.mjs.map +1 -1
- package/dist/actions/gen-docs.mjs.map +1 -1
- package/dist/actions/index.mjs +367 -160
- package/dist/actions/index.mjs.map +1 -1
- package/dist/actions/knip.mjs.map +1 -1
- package/dist/actions/lint.mjs.map +1 -1
- package/dist/actions/publint.mjs.map +1 -1
- package/dist/actions/publish.mjs.map +1 -1
- package/dist/actions/readme-gen.mjs +136 -20
- package/dist/actions/readme-gen.mjs.map +1 -1
- package/dist/actions/readme-init.mjs +83 -0
- package/dist/actions/readme-init.mjs.map +1 -0
- package/dist/actions/rebuild.mjs.map +1 -1
- package/dist/actions/reinstall.mjs.map +1 -1
- package/dist/actions/relint.mjs.map +1 -1
- package/dist/actions/retest.mjs +2 -2
- package/dist/actions/retest.mjs.map +1 -1
- package/dist/actions/sonar.mjs.map +1 -1
- package/dist/actions/test.mjs.map +1 -1
- package/dist/actions/up.mjs.map +1 -1
- package/dist/actions/updo.mjs.map +1 -1
- package/dist/actions/upplug.mjs.map +1 -1
- package/dist/actions/upyarn.mjs.map +1 -1
- package/dist/bin/xy.mjs +982 -642
- package/dist/bin/xy.mjs.map +1 -1
- package/dist/index.d.ts +46 -13
- package/dist/index.mjs +1044 -695
- package/dist/index.mjs.map +1 -1
- package/dist/lib/claudeMdTemplate.mjs +28 -3
- package/dist/lib/claudeMdTemplate.mjs.map +1 -1
- package/dist/lib/generateReadmeFiles.mjs +118 -21
- package/dist/lib/generateReadmeFiles.mjs.map +1 -1
- package/dist/lib/index.mjs +146 -24
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/runSteps.mjs.map +1 -1
- package/dist/lib/runXy.mjs.map +1 -1
- package/dist/xy/{xyBuildCommands.mjs → build-commands/build.mjs} +107 -94
- package/dist/xy/build-commands/build.mjs.map +1 -0
- package/dist/xy/build-commands/index.mjs +502 -0
- package/dist/xy/build-commands/index.mjs.map +1 -0
- package/dist/xy/common/claude/commandsCommand.mjs +111 -0
- package/dist/xy/common/claude/commandsCommand.mjs.map +1 -0
- package/dist/xy/common/claude/index.mjs +441 -0
- package/dist/xy/common/claude/index.mjs.map +1 -0
- package/dist/xy/common/claude/initCommand.mjs +393 -0
- package/dist/xy/common/claude/initCommand.mjs.map +1 -0
- package/dist/xy/common/claude/rulesCommand.mjs +133 -0
- package/dist/xy/common/claude/rulesCommand.mjs.map +1 -0
- package/dist/xy/common/claude/settingsCommand.mjs +90 -0
- package/dist/xy/common/claude/settingsCommand.mjs.map +1 -0
- package/dist/xy/common/claude/skillsCommand.mjs +129 -0
- package/dist/xy/common/claude/skillsCommand.mjs.map +1 -0
- package/dist/xy/common/cleanDocsCommand.mjs +45 -0
- package/dist/xy/common/cleanDocsCommand.mjs.map +1 -0
- package/dist/xy/common/deadCommand.mjs +116 -0
- package/dist/xy/common/deadCommand.mjs.map +1 -0
- package/dist/xy/common/genDocsCommand.mjs +125 -0
- package/dist/xy/common/genDocsCommand.mjs.map +1 -0
- package/dist/xy/common/gitignoreGenCommand.mjs +98 -0
- package/dist/xy/common/gitignoreGenCommand.mjs.map +1 -0
- package/dist/xy/common/gitlintCommand.mjs +82 -0
- package/dist/xy/common/gitlintCommand.mjs.map +1 -0
- package/dist/xy/{xyCommonCommands.mjs → common/index.mjs} +561 -242
- package/dist/xy/common/index.mjs.map +1 -0
- package/dist/xy/common/licenseCommand.mjs +100 -0
- package/dist/xy/common/licenseCommand.mjs.map +1 -0
- package/dist/xy/common/npmignoreGenCommand.mjs +98 -0
- package/dist/xy/common/npmignoreGenCommand.mjs.map +1 -0
- package/dist/xy/common/readme/genCommand.mjs +321 -0
- package/dist/xy/common/readme/genCommand.mjs.map +1 -0
- package/dist/xy/common/readme/index.mjs +361 -0
- package/dist/xy/common/readme/index.mjs.map +1 -0
- package/dist/xy/common/readme/initCommand.mjs +103 -0
- package/dist/xy/common/readme/initCommand.mjs.map +1 -0
- package/dist/xy/common/retestCommand.mjs +111 -0
- package/dist/xy/common/retestCommand.mjs.map +1 -0
- package/dist/xy/common/testCommand.mjs +108 -0
- package/dist/xy/common/testCommand.mjs.map +1 -0
- package/dist/xy/common/upplugCommand.mjs +113 -0
- package/dist/xy/common/upplugCommand.mjs.map +1 -0
- package/dist/xy/common/upyarnCommand.mjs +108 -0
- package/dist/xy/common/upyarnCommand.mjs.map +1 -0
- package/dist/xy/common/yarn3OnlyCommand.mjs +70 -0
- package/dist/xy/common/yarn3OnlyCommand.mjs.map +1 -0
- package/dist/xy/deploy/deployCommand.mjs +139 -0
- package/dist/xy/deploy/deployCommand.mjs.map +1 -0
- package/dist/xy/deploy/deployMajorCommand.mjs +139 -0
- package/dist/xy/deploy/deployMajorCommand.mjs.map +1 -0
- package/dist/xy/deploy/deployMinorCommand.mjs +139 -0
- package/dist/xy/deploy/deployMinorCommand.mjs.map +1 -0
- package/dist/xy/deploy/deployNextCommand.mjs +139 -0
- package/dist/xy/deploy/deployNextCommand.mjs.map +1 -0
- package/dist/xy/{xyDeployCommands.mjs → deploy/index.mjs} +53 -53
- package/dist/xy/deploy/index.mjs.map +1 -0
- package/dist/xy/deploy/publishCommand.mjs +108 -0
- package/dist/xy/deploy/publishCommand.mjs.map +1 -0
- package/dist/xy/index.mjs +982 -642
- package/dist/xy/index.mjs.map +1 -1
- package/dist/xy/install/cleanCommand.mjs +140 -0
- package/dist/xy/install/cleanCommand.mjs.map +1 -0
- package/dist/xy/install/dupdepsCommand.mjs +191 -0
- package/dist/xy/install/dupdepsCommand.mjs.map +1 -0
- package/dist/xy/{xyInstallCommands.mjs → install/index.mjs} +71 -68
- package/dist/xy/install/index.mjs.map +1 -0
- package/dist/xy/install/reinstallCommand.mjs +140 -0
- package/dist/xy/install/reinstallCommand.mjs.map +1 -0
- package/dist/xy/install/staticsCommand.mjs +191 -0
- package/dist/xy/install/staticsCommand.mjs.map +1 -0
- package/dist/{actions/clean-jest.mjs → xy/install/upCommand.mjs} +15 -6
- package/dist/xy/install/upCommand.mjs.map +1 -0
- package/dist/xy/install/updoCommand.mjs +112 -0
- package/dist/xy/install/updoCommand.mjs.map +1 -0
- package/dist/xy/lint/cycleCommand.mjs +163 -0
- package/dist/xy/lint/cycleCommand.mjs.map +1 -0
- package/dist/xy/lint/deplintCommand.mjs +814 -0
- package/dist/xy/lint/deplintCommand.mjs.map +1 -0
- package/dist/xy/lint/fixCommand.mjs +168 -0
- package/dist/xy/lint/fixCommand.mjs.map +1 -0
- package/dist/xy/{xyLintCommands.mjs → lint/index.mjs} +176 -145
- package/dist/xy/lint/index.mjs.map +1 -0
- package/dist/xy/lint/knipCommand.mjs +121 -0
- package/dist/xy/lint/knipCommand.mjs.map +1 -0
- package/dist/xy/lint/lintCommand.mjs +186 -0
- package/dist/xy/lint/lintCommand.mjs.map +1 -0
- package/dist/xy/lint/publintCommand.mjs +187 -0
- package/dist/xy/lint/publintCommand.mjs.map +1 -0
- package/dist/xy/lint/relintCommand.mjs +163 -0
- package/dist/xy/lint/relintCommand.mjs.map +1 -0
- package/dist/xy/lint/sonarCommand.mjs +121 -0
- package/dist/xy/lint/sonarCommand.mjs.map +1 -0
- package/dist/xy/xy.mjs +980 -640
- package/dist/xy/xy.mjs.map +1 -1
- package/package.json +2 -2
- package/templates/claude/skills/xylabs-e2e-setup/SKILL.md +196 -0
- package/templates/readme/README.body.md +11 -0
- package/templates/readme/README.template.md +22 -0
- package/dist/actions/clean-jest.mjs.map +0 -1
- package/dist/xy/xyBuildCommands.mjs.map +0 -1
- package/dist/xy/xyCommonCommands.mjs.map +0 -1
- package/dist/xy/xyDeployCommands.mjs.map +0 -1
- package/dist/xy/xyInstallCommands.mjs.map +0 -1
- package/dist/xy/xyLintCommands.mjs.map +0 -1
- /package/templates/{CLAUDE-project.md → claude/CLAUDE-project.md} +0 -0
- /package/templates/{commands → claude/commands}/xylabs-build.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-clean.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-compile.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-cycle.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-deplint.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-deploy-major.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-deploy-minor.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-deploy.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-fix.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-knip.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-lint.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-publint.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-rebuild.md +0 -0
- /package/templates/{commands → claude/commands}/xylabs-test.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-architecture.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-build.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-dependencies.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-error-handling.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-frameworks.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-git-workflow.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-linting.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-naming.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-style.md +0 -0
- /package/templates/{rules → claude/rules}/xylabs-typescript.md +0 -0
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// src/lib/claudeMdTemplate.ts
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
readdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
statSync
|
|
6
|
+
} from "fs";
|
|
3
7
|
import { createRequire } from "module";
|
|
4
8
|
import PATH from "path";
|
|
5
9
|
var require2 = createRequire(import.meta.url);
|
|
6
10
|
var packageRoot = PATH.dirname(require2.resolve("@xylabs/ts-scripts-yarn3/package.json"));
|
|
7
|
-
var templatesDir = PATH.resolve(packageRoot, "templates");
|
|
11
|
+
var templatesDir = PATH.resolve(packageRoot, "templates", "claude");
|
|
8
12
|
var XYLABS_RULES_PREFIX = "xylabs-";
|
|
9
13
|
var XYLABS_COMMANDS_PREFIX = "xylabs-";
|
|
14
|
+
var XYLABS_SKILLS_PREFIX = "xylabs-";
|
|
10
15
|
var claudeMdRuleTemplates = () => {
|
|
11
16
|
const rulesDir = PATH.resolve(templatesDir, "rules");
|
|
12
17
|
const files = readdirSync(rulesDir).filter((f) => f.startsWith(XYLABS_RULES_PREFIX) && f.endsWith(".md"));
|
|
@@ -25,12 +30,32 @@ var claudeCommandTemplates = () => {
|
|
|
25
30
|
}
|
|
26
31
|
return result;
|
|
27
32
|
};
|
|
33
|
+
var claudeSkillTemplates = () => {
|
|
34
|
+
const skillsDir = PATH.resolve(templatesDir, "skills");
|
|
35
|
+
const dirs = readdirSync(skillsDir).filter(
|
|
36
|
+
(f) => f.startsWith(XYLABS_SKILLS_PREFIX) && statSync(PATH.resolve(skillsDir, f)).isDirectory()
|
|
37
|
+
);
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const dir of dirs) {
|
|
40
|
+
const dirPath = PATH.resolve(skillsDir, dir);
|
|
41
|
+
const files = readdirSync(dirPath, { recursive: true, encoding: "utf8" });
|
|
42
|
+
result[dir] = {};
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
if (statSync(PATH.resolve(dirPath, file)).isFile()) {
|
|
45
|
+
result[dir][file] = readFileSync(PATH.resolve(dirPath, file), "utf8");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
28
51
|
var claudeMdProjectTemplate = () => readFileSync(PATH.resolve(templatesDir, "CLAUDE-project.md"), "utf8");
|
|
29
52
|
export {
|
|
30
53
|
XYLABS_COMMANDS_PREFIX,
|
|
31
54
|
XYLABS_RULES_PREFIX,
|
|
55
|
+
XYLABS_SKILLS_PREFIX,
|
|
32
56
|
claudeCommandTemplates,
|
|
33
57
|
claudeMdProjectTemplate,
|
|
34
|
-
claudeMdRuleTemplates
|
|
58
|
+
claudeMdRuleTemplates,
|
|
59
|
+
claudeSkillTemplates
|
|
35
60
|
};
|
|
36
61
|
//# sourceMappingURL=claudeMdTemplate.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/claudeMdTemplate.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/lib/claudeMdTemplate.ts"],"sourcesContent":["import {\n readdirSync, readFileSync, statSync,\n} from 'node:fs'\nimport { createRequire } from 'node:module'\nimport PATH from 'node:path'\n\nconst require = createRequire(import.meta.url)\nconst packageRoot = PATH.dirname(require.resolve('@xylabs/ts-scripts-yarn3/package.json'))\nconst templatesDir = PATH.resolve(packageRoot, 'templates', 'claude')\n\nexport const XYLABS_RULES_PREFIX = 'xylabs-'\nexport const XYLABS_COMMANDS_PREFIX = 'xylabs-'\nexport const XYLABS_SKILLS_PREFIX = 'xylabs-'\n\nexport const claudeMdRuleTemplates = (): Record<string, string> => {\n const rulesDir = PATH.resolve(templatesDir, 'rules')\n const files = readdirSync(rulesDir).filter(f => f.startsWith(XYLABS_RULES_PREFIX) && f.endsWith('.md'))\n const result: Record<string, string> = {}\n for (const file of files) {\n result[file] = readFileSync(PATH.resolve(rulesDir, file), 'utf8')\n }\n return result\n}\n\nexport const claudeCommandTemplates = (): Record<string, string> => {\n const commandsDir = PATH.resolve(templatesDir, 'commands')\n const files = readdirSync(commandsDir).filter(f => f.startsWith(XYLABS_COMMANDS_PREFIX) && f.endsWith('.md'))\n const result: Record<string, string> = {}\n for (const file of files) {\n result[file] = readFileSync(PATH.resolve(commandsDir, file), 'utf8')\n }\n return result\n}\n\n// Returns { 'xylabs-foo': { 'SKILL.md': '...', 'other.ts': '...' } }\nexport const claudeSkillTemplates = (): Record<string, Record<string, string>> => {\n const skillsDir = PATH.resolve(templatesDir, 'skills')\n const dirs = readdirSync(skillsDir).filter(\n f => f.startsWith(XYLABS_SKILLS_PREFIX) && statSync(PATH.resolve(skillsDir, f)).isDirectory(),\n )\n const result: Record<string, Record<string, string>> = {}\n for (const dir of dirs) {\n const dirPath = PATH.resolve(skillsDir, dir)\n const files = readdirSync(dirPath, { recursive: true, encoding: 'utf8' }) as string[]\n result[dir] = {}\n for (const file of files) {\n if (statSync(PATH.resolve(dirPath, file)).isFile()) {\n result[dir][file] = readFileSync(PATH.resolve(dirPath, file), 'utf8')\n }\n }\n }\n return result\n}\n\nexport const claudeMdProjectTemplate = (): string =>\n readFileSync(PATH.resolve(templatesDir, 'CLAUDE-project.md'), 'utf8')\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAAa;AAAA,EAAc;AAAA,OACtB;AACP,SAAS,qBAAqB;AAC9B,OAAO,UAAU;AAEjB,IAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,cAAc,KAAK,QAAQA,SAAQ,QAAQ,uCAAuC,CAAC;AACzF,IAAM,eAAe,KAAK,QAAQ,aAAa,aAAa,QAAQ;AAE7D,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAE7B,IAAM,wBAAwB,MAA8B;AACjE,QAAM,WAAW,KAAK,QAAQ,cAAc,OAAO;AACnD,QAAM,QAAQ,YAAY,QAAQ,EAAE,OAAO,OAAK,EAAE,WAAW,mBAAmB,KAAK,EAAE,SAAS,KAAK,CAAC;AACtG,QAAM,SAAiC,CAAC;AACxC,aAAW,QAAQ,OAAO;AACxB,WAAO,IAAI,IAAI,aAAa,KAAK,QAAQ,UAAU,IAAI,GAAG,MAAM;AAAA,EAClE;AACA,SAAO;AACT;AAEO,IAAM,yBAAyB,MAA8B;AAClE,QAAM,cAAc,KAAK,QAAQ,cAAc,UAAU;AACzD,QAAM,QAAQ,YAAY,WAAW,EAAE,OAAO,OAAK,EAAE,WAAW,sBAAsB,KAAK,EAAE,SAAS,KAAK,CAAC;AAC5G,QAAM,SAAiC,CAAC;AACxC,aAAW,QAAQ,OAAO;AACxB,WAAO,IAAI,IAAI,aAAa,KAAK,QAAQ,aAAa,IAAI,GAAG,MAAM;AAAA,EACrE;AACA,SAAO;AACT;AAGO,IAAM,uBAAuB,MAA8C;AAChF,QAAM,YAAY,KAAK,QAAQ,cAAc,QAAQ;AACrD,QAAM,OAAO,YAAY,SAAS,EAAE;AAAA,IAClC,OAAK,EAAE,WAAW,oBAAoB,KAAK,SAAS,KAAK,QAAQ,WAAW,CAAC,CAAC,EAAE,YAAY;AAAA,EAC9F;AACA,QAAM,SAAiD,CAAC;AACxD,aAAW,OAAO,MAAM;AACtB,UAAM,UAAU,KAAK,QAAQ,WAAW,GAAG;AAC3C,UAAM,QAAQ,YAAY,SAAS,EAAE,WAAW,MAAM,UAAU,OAAO,CAAC;AACxE,WAAO,GAAG,IAAI,CAAC;AACf,eAAW,QAAQ,OAAO;AACxB,UAAI,SAAS,KAAK,QAAQ,SAAS,IAAI,CAAC,EAAE,OAAO,GAAG;AAClD,eAAO,GAAG,EAAE,IAAI,IAAI,aAAa,KAAK,QAAQ,SAAS,IAAI,GAAG,MAAM;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,0BAA0B,MACrC,aAAa,KAAK,QAAQ,cAAc,mBAAmB,GAAG,MAAM;","names":["require"]}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// src/lib/generateReadmeFiles.ts
|
|
2
2
|
import { execSync } from "child_process";
|
|
3
|
-
import FS from "fs";
|
|
4
|
-
import {
|
|
3
|
+
import FS, { readFileSync } from "fs";
|
|
4
|
+
import {
|
|
5
|
+
mkdir,
|
|
6
|
+
readFile,
|
|
7
|
+
writeFile
|
|
8
|
+
} from "fs/promises";
|
|
9
|
+
import { createRequire } from "module";
|
|
5
10
|
import PATH from "path";
|
|
11
|
+
import { createInterface } from "readline";
|
|
6
12
|
import chalk from "chalk";
|
|
7
13
|
|
|
8
14
|
// src/lib/yarn/workspace/yarnWorkspaces.ts
|
|
@@ -31,6 +37,9 @@ var INIT_CWD = () => {
|
|
|
31
37
|
};
|
|
32
38
|
|
|
33
39
|
// src/lib/generateReadmeFiles.ts
|
|
40
|
+
var require2 = createRequire(import.meta.url);
|
|
41
|
+
var packageRoot = PATH.dirname(require2.resolve("@xylabs/ts-scripts-yarn3/package.json"));
|
|
42
|
+
var readmeTemplatesDir = PATH.resolve(packageRoot, "templates", "readme");
|
|
34
43
|
function fillTemplate(template, data) {
|
|
35
44
|
const additionalData = { ...data, safeName: data.name.replaceAll("/", "__").replaceAll("@", "") };
|
|
36
45
|
return template.replaceAll(/\{\{(.*?)\}\}/g, (_, key) => additionalData[key.trim()] ?? "");
|
|
@@ -120,41 +129,129 @@ ${indent}### ${item.name}
|
|
|
120
129
|
}
|
|
121
130
|
return content;
|
|
122
131
|
}
|
|
132
|
+
function askConfirmation(question) {
|
|
133
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
134
|
+
return new Promise((resolve) => {
|
|
135
|
+
rl.question(question, (answer) => {
|
|
136
|
+
rl.close();
|
|
137
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
var DEFAULT_README_TEMPLATE = readFileSync(PATH.resolve(readmeTemplatesDir, "README.template.md"), "utf8");
|
|
142
|
+
var DEFAULT_README_BODY = readFileSync(PATH.resolve(readmeTemplatesDir, "README.body.md"), "utf8");
|
|
143
|
+
function applyLogoConfig(template, logoUrl, logoLinkUrl) {
|
|
144
|
+
let result = template;
|
|
145
|
+
if (logoUrl) {
|
|
146
|
+
result = result.replace(/\[logo]: .+/, `[logo]: ${logoUrl}`);
|
|
147
|
+
if (logoLinkUrl) {
|
|
148
|
+
result = result.replace(/\[!\[logo]\[]][^)]*\)/, `[![logo][]](${logoLinkUrl})`);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
result = result.replace(/\[!\[logo]\[]][^\n]*\n*/, "");
|
|
152
|
+
result = result.replace(/\[logo]: [^\n]*\n?/, "");
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
function resolveTemplatePath(templatePath) {
|
|
157
|
+
const cwd = INIT_CWD() ?? ".";
|
|
158
|
+
return templatePath ?? PATH.join(cwd, ".xy", "README.template.md");
|
|
159
|
+
}
|
|
160
|
+
async function loadOrCreateTemplate(resolvedTemplatePath) {
|
|
161
|
+
try {
|
|
162
|
+
const template = await readFile(resolvedTemplatePath, "utf8");
|
|
163
|
+
return { created: false, template };
|
|
164
|
+
} catch {
|
|
165
|
+
console.log(chalk.yellow(`Template not found: ${resolvedTemplatePath}`));
|
|
166
|
+
const shouldCreate = await askConfirmation("Would you like to create a stock template? (y/N) ");
|
|
167
|
+
if (!shouldCreate) {
|
|
168
|
+
throw new Error("Template creation declined");
|
|
169
|
+
}
|
|
170
|
+
const template = DEFAULT_README_TEMPLATE;
|
|
171
|
+
await scaffoldTemplate(resolvedTemplatePath, template);
|
|
172
|
+
return { created: true, template };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async function scaffoldTemplate(resolvedTemplatePath, template) {
|
|
176
|
+
const xyDir = PATH.dirname(resolvedTemplatePath);
|
|
177
|
+
await mkdir(xyDir, { recursive: true });
|
|
178
|
+
await writeFile(resolvedTemplatePath, template);
|
|
179
|
+
console.log(chalk.green(`Created template: ${resolvedTemplatePath}`));
|
|
180
|
+
const bodyPath = PATH.join(xyDir, "README.body.md");
|
|
181
|
+
await writeFile(bodyPath, DEFAULT_README_BODY);
|
|
182
|
+
console.log(chalk.green(`Created body template: ${bodyPath}`));
|
|
183
|
+
}
|
|
184
|
+
async function resolveBody(location, defaultBody) {
|
|
185
|
+
const localBodyPath = PATH.join(location, "README.body.md");
|
|
186
|
+
try {
|
|
187
|
+
return await readFile(localBodyPath, "utf8");
|
|
188
|
+
} catch {
|
|
189
|
+
return defaultBody;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function generateReadmeForWorkspace(location, name, template, defaultBody, typedoc, verbose) {
|
|
193
|
+
try {
|
|
194
|
+
const pkgJsonPath = PATH.join(location, "package.json");
|
|
195
|
+
const pkgJson = JSON.parse(await readFile(pkgJsonPath, "utf8"));
|
|
196
|
+
const body = await resolveBody(location, defaultBody);
|
|
197
|
+
const typedocContent = typedoc ? generateTypedoc(location, ["src/index*.ts"]) : "";
|
|
198
|
+
const readmeContent = fillTemplate(template, {
|
|
199
|
+
...pkgJson,
|
|
200
|
+
body,
|
|
201
|
+
typedoc: typedocContent
|
|
202
|
+
});
|
|
203
|
+
await writeFile(PATH.join(location, "README.md"), readmeContent);
|
|
204
|
+
if (verbose) console.log(chalk.green(` ${name}`));
|
|
205
|
+
return true;
|
|
206
|
+
} catch (ex) {
|
|
207
|
+
const error = ex;
|
|
208
|
+
console.warn(chalk.yellow(` Skipped ${location}: ${error.message}`));
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
123
212
|
async function generateReadmeFiles({
|
|
213
|
+
logoLinkUrl,
|
|
214
|
+
logoUrl,
|
|
124
215
|
pkg,
|
|
125
216
|
templatePath,
|
|
126
217
|
typedoc = false,
|
|
127
|
-
verbose
|
|
218
|
+
verbose = false
|
|
128
219
|
}) {
|
|
129
220
|
console.log(chalk.green("Generate README Files"));
|
|
130
|
-
const
|
|
131
|
-
const resolvedTemplatePath = templatePath ?? PATH.join(cwd, "scripts", "README.template.md");
|
|
221
|
+
const resolvedTemplatePath = resolveTemplatePath(templatePath);
|
|
132
222
|
let template;
|
|
223
|
+
let templateCreated;
|
|
133
224
|
try {
|
|
134
|
-
template = await
|
|
225
|
+
({ template, created: templateCreated } = await loadOrCreateTemplate(resolvedTemplatePath));
|
|
135
226
|
} catch {
|
|
136
|
-
console.error(chalk.red(`Template not found: ${resolvedTemplatePath}`));
|
|
137
227
|
return 1;
|
|
138
228
|
}
|
|
139
|
-
|
|
229
|
+
template = applyLogoConfig(template, logoUrl, logoLinkUrl);
|
|
230
|
+
if (templateCreated) {
|
|
231
|
+
console.log(chalk.green("Generating README files for all packages..."));
|
|
232
|
+
}
|
|
233
|
+
const xyDir = PATH.dirname(resolvedTemplatePath);
|
|
234
|
+
const xyBodyPath = PATH.join(xyDir, "README.body.md");
|
|
235
|
+
let defaultBody;
|
|
236
|
+
try {
|
|
237
|
+
defaultBody = await readFile(xyBodyPath, "utf8");
|
|
238
|
+
} catch {
|
|
239
|
+
defaultBody = DEFAULT_README_BODY;
|
|
240
|
+
}
|
|
241
|
+
const workspaces = pkg && !templateCreated ? [yarnWorkspace(pkg)] : yarnWorkspaces();
|
|
140
242
|
let failed = false;
|
|
141
243
|
for (const { location, name } of workspaces) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const pkgJson = JSON.parse(await readFile(pkgJsonPath, "utf8"));
|
|
145
|
-
const typedocContent = typedoc ? generateTypedoc(location, ["src/index*.ts"]) : "";
|
|
146
|
-
const readmeContent = fillTemplate(template, { ...pkgJson, typedoc: typedocContent });
|
|
147
|
-
await writeFile(PATH.join(location, "README.md"), readmeContent);
|
|
148
|
-
if (verbose) console.log(chalk.green(` ${name}`));
|
|
149
|
-
} catch (ex) {
|
|
150
|
-
const error = ex;
|
|
151
|
-
console.warn(chalk.yellow(` Skipped ${location}: ${error.message}`));
|
|
152
|
-
failed = true;
|
|
153
|
-
}
|
|
244
|
+
const success = await generateReadmeForWorkspace(location, name, template, defaultBody, typedoc, verbose);
|
|
245
|
+
if (!success) failed = true;
|
|
154
246
|
}
|
|
155
247
|
return failed ? 1 : 0;
|
|
156
248
|
}
|
|
157
249
|
export {
|
|
158
|
-
|
|
250
|
+
DEFAULT_README_BODY,
|
|
251
|
+
DEFAULT_README_TEMPLATE,
|
|
252
|
+
applyLogoConfig,
|
|
253
|
+
generateReadmeFiles,
|
|
254
|
+
resolveTemplatePath,
|
|
255
|
+
scaffoldTemplate
|
|
159
256
|
};
|
|
160
257
|
//# sourceMappingURL=generateReadmeFiles.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/generateReadmeFiles.ts","../../src/lib/yarn/workspace/yarnWorkspaces.ts","../../src/lib/yarn/workspace/yarnWorkspace.ts","../../src/lib/yarn/yarnInitCwd.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport FS from 'node:fs'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport PATH from 'node:path'\n\nimport chalk from 'chalk'\n\nimport {\n INIT_CWD, yarnWorkspace, yarnWorkspaces,\n} from './yarn/index.ts'\n\ninterface GenerateReadmeFilesParams {\n pkg?: string\n templatePath?: string\n typedoc?: boolean\n verbose?: boolean\n}\n\nfunction fillTemplate(template: string, data: Record<string, string>): string {\n const additionalData: Record<string, string> = { ...data, safeName: data.name.replaceAll('/', '__').replaceAll('@', '') }\n return template.replaceAll(/\\{\\{(.*?)\\}\\}/g, (_, key: string) => additionalData[key.trim()] ?? '')\n}\n\nfunction generateTypedoc(packageLocation: string, entryPoints: string[]): string {\n const tempDir = PATH.join(packageLocation, '.temp-typedoc')\n\n try {\n if (!FS.existsSync(tempDir)) {\n FS.mkdirSync(tempDir, { recursive: true })\n }\n\n const typedocConfig = {\n disableSources: true,\n entryPointStrategy: 'expand',\n entryPoints: entryPoints.map(ep => PATH.resolve(packageLocation, ep)),\n excludeExternals: true,\n excludeInternal: true,\n excludePrivate: true,\n githubPages: false,\n hideBreadcrumbs: true,\n hideGenerator: true,\n hidePageTitle: true,\n out: tempDir,\n plugin: ['typedoc-plugin-markdown'],\n readme: 'none',\n skipErrorChecking: true,\n sort: ['source-order'],\n theme: 'markdown',\n useCodeBlocks: true,\n }\n\n const typedocJsonPath = PATH.join(tempDir, 'typedoc.json')\n FS.writeFileSync(typedocJsonPath, JSON.stringify(typedocConfig, null, 2))\n\n try {\n execSync(`npx typedoc --options ${typedocJsonPath}`, {\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n } catch {\n return ''\n }\n\n return consolidateMarkdown(tempDir)\n } catch {\n return ''\n } finally {\n try {\n FS.rmSync(tempDir, { force: true, recursive: true })\n } catch {\n // ignore cleanup errors\n }\n }\n}\n\nfunction consolidateMarkdown(tempDir: string): string {\n let consolidated = '## Reference\\n\\n'\n\n const mainReadmePath = PATH.join(tempDir, 'README.md')\n if (FS.existsSync(mainReadmePath)) {\n const mainContent = FS.readFileSync(mainReadmePath, 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '')\n .replace(/^# .+\\n/, '')\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)')\n\n consolidated += mainContent + '\\n\\n'\n }\n\n consolidated += processDirectory(tempDir)\n\n return consolidated\n .replaceAll(/\\n\\n\\n+/g, '\\n\\n')\n .replaceAll(/^#### /gm, '### ')\n .replaceAll(/^##### /gm, '#### ')\n .replaceAll(/^###### /gm, '##### ')\n}\n\nfunction processDirectory(dir: string, level = 0): string {\n const indent = ' '.repeat(level)\n let content = ''\n\n try {\n const items = FS.readdirSync(dir, { withFileTypes: true })\n\n for (const item of items) {\n if (item.isDirectory()) continue\n if (item.name === 'README.md' || !item.name.endsWith('.md')) continue\n\n const fileContent = FS.readFileSync(PATH.join(dir, item.name), 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '')\n const moduleName = item.name.replace('.md', '')\n\n content += `\\n\\n${indent}### <a id=\"${moduleName}\"></a>${moduleName}\\n\\n`\n content += fileContent\n .replace(/^# .+\\n/, '')\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)')\n }\n\n for (const item of items) {\n if (!item.isDirectory()) continue\n if (item.name === 'spec' || item.name.includes('.spec')) continue\n\n content += `\\n\\n${indent}### ${item.name}\\n`\n content += processDirectory(PATH.join(dir, item.name), level + 1)\n }\n } catch {\n // skip unreadable directories\n }\n\n return content\n}\n\nexport async function generateReadmeFiles({\n pkg, templatePath, typedoc = false, verbose,\n}: GenerateReadmeFilesParams): Promise<number> {\n console.log(chalk.green('Generate README Files'))\n const cwd = INIT_CWD() ?? '.'\n const resolvedTemplatePath = templatePath ?? PATH.join(cwd, 'scripts', 'README.template.md')\n\n let template: string\n try {\n template = await readFile(resolvedTemplatePath, 'utf8')\n } catch {\n console.error(chalk.red(`Template not found: ${resolvedTemplatePath}`))\n return 1\n }\n\n const workspaces = pkg ? [yarnWorkspace(pkg)] : yarnWorkspaces()\n let failed = false\n\n for (const { location, name } of workspaces) {\n try {\n const pkgJsonPath = PATH.join(location, 'package.json')\n const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf8'))\n const typedocContent = typedoc ? generateTypedoc(location, ['src/index*.ts']) : ''\n const readmeContent = fillTemplate(template, { ...pkgJson, typedoc: typedocContent })\n await writeFile(PATH.join(location, 'README.md'), readmeContent)\n if (verbose) console.log(chalk.green(` ${name}`))\n } catch (ex) {\n const error = ex as Error\n console.warn(chalk.yellow(` Skipped ${location}: ${error.message}`))\n failed = true\n }\n }\n\n return failed ? 1 : 0\n}\n","import { spawnSync } from 'node:child_process'\n\nimport type { Workspace } from './Workspace.ts'\n\nexport const yarnWorkspaces = (): Workspace[] => {\n const result = spawnSync('yarn', ['workspaces', 'list', '--json', '--recursive'], { encoding: 'utf8', shell: true })\n if (result.error) {\n throw result.error\n }\n return (\n result.stdout\n .toString()\n // NOTE: This probably doesn't work on Windows\n // TODO: Replace /r/n with /n first\n .split('\\n')\n .slice(0, -1)\n .map((item) => {\n return JSON.parse(item)\n })\n )\n}\n","import type { Workspace } from './Workspace.ts'\nimport { yarnWorkspaces } from './yarnWorkspaces.ts'\n\nexport const yarnWorkspace = (pkg: string): Workspace => {\n const workspace = yarnWorkspaces().find(({ name }) => name === pkg)\n if (!workspace) throw new Error(`Workspace ${pkg} not found`)\n return workspace\n}\n","export const INIT_CWD = () => {\n if (!process.env.INIT_CWD) console.error('Missing INIT_CWD')\n return process.env.INIT_CWD\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/generateReadmeFiles.ts","../../src/lib/yarn/workspace/yarnWorkspaces.ts","../../src/lib/yarn/workspace/yarnWorkspace.ts","../../src/lib/yarn/yarnInitCwd.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport FS, { readFileSync } from 'node:fs'\nimport {\n mkdir, readFile, writeFile,\n} from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport PATH from 'node:path'\nimport { createInterface } from 'node:readline'\n\nimport chalk from 'chalk'\n\nimport {\n INIT_CWD, yarnWorkspace, yarnWorkspaces,\n} from './yarn/index.ts'\n\nconst require = createRequire(import.meta.url)\nconst packageRoot = PATH.dirname(require.resolve('@xylabs/ts-scripts-yarn3/package.json'))\nconst readmeTemplatesDir = PATH.resolve(packageRoot, 'templates', 'readme')\n\ninterface GenerateReadmeFilesParams {\n logoLinkUrl?: string\n logoUrl?: string\n pkg?: string\n templatePath?: string\n typedoc?: boolean\n verbose?: boolean\n}\n\nfunction fillTemplate(template: string, data: Record<string, string>): string {\n const additionalData: Record<string, string> = { ...data, safeName: data.name.replaceAll('/', '__').replaceAll('@', '') }\n return template.replaceAll(/\\{\\{(.*?)\\}\\}/g, (_, key: string) => additionalData[key.trim()] ?? '')\n}\n\nfunction generateTypedoc(packageLocation: string, entryPoints: string[]): string {\n const tempDir = PATH.join(packageLocation, '.temp-typedoc')\n\n try {\n if (!FS.existsSync(tempDir)) {\n FS.mkdirSync(tempDir, { recursive: true })\n }\n\n const typedocConfig = {\n disableSources: true,\n entryPointStrategy: 'expand',\n entryPoints: entryPoints.map(ep => PATH.resolve(packageLocation, ep)),\n excludeExternals: true,\n excludeInternal: true,\n excludePrivate: true,\n githubPages: false,\n hideBreadcrumbs: true,\n hideGenerator: true,\n hidePageTitle: true,\n out: tempDir,\n plugin: ['typedoc-plugin-markdown'],\n readme: 'none',\n skipErrorChecking: true,\n sort: ['source-order'],\n theme: 'markdown',\n useCodeBlocks: true,\n }\n\n const typedocJsonPath = PATH.join(tempDir, 'typedoc.json')\n FS.writeFileSync(typedocJsonPath, JSON.stringify(typedocConfig, null, 2))\n\n try {\n execSync(`npx typedoc --options ${typedocJsonPath}`, {\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n } catch {\n return ''\n }\n\n return consolidateMarkdown(tempDir)\n } catch {\n return ''\n } finally {\n try {\n FS.rmSync(tempDir, { force: true, recursive: true })\n } catch {\n // ignore cleanup errors\n }\n }\n}\n\nfunction consolidateMarkdown(tempDir: string): string {\n let consolidated = '## Reference\\n\\n'\n\n const mainReadmePath = PATH.join(tempDir, 'README.md')\n if (FS.existsSync(mainReadmePath)) {\n const mainContent = FS.readFileSync(mainReadmePath, 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '')\n .replace(/^# .+\\n/, '')\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)')\n\n consolidated += mainContent + '\\n\\n'\n }\n\n consolidated += processDirectory(tempDir)\n\n return consolidated\n .replaceAll(/\\n\\n\\n+/g, '\\n\\n')\n .replaceAll(/^#### /gm, '### ')\n .replaceAll(/^##### /gm, '#### ')\n .replaceAll(/^###### /gm, '##### ')\n}\n\nfunction processDirectory(dir: string, level = 0): string {\n const indent = ' '.repeat(level)\n let content = ''\n\n try {\n const items = FS.readdirSync(dir, { withFileTypes: true })\n\n for (const item of items) {\n if (item.isDirectory()) continue\n if (item.name === 'README.md' || !item.name.endsWith('.md')) continue\n\n const fileContent = FS.readFileSync(PATH.join(dir, item.name), 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '')\n const moduleName = item.name.replace('.md', '')\n\n content += `\\n\\n${indent}### <a id=\"${moduleName}\"></a>${moduleName}\\n\\n`\n content += fileContent\n .replace(/^# .+\\n/, '')\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)')\n }\n\n for (const item of items) {\n if (!item.isDirectory()) continue\n if (item.name === 'spec' || item.name.includes('.spec')) continue\n\n content += `\\n\\n${indent}### ${item.name}\\n`\n content += processDirectory(PATH.join(dir, item.name), level + 1)\n }\n } catch {\n // skip unreadable directories\n }\n\n return content\n}\n\nfunction askConfirmation(question: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close()\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes')\n })\n })\n}\n\nexport const DEFAULT_README_TEMPLATE = readFileSync(PATH.resolve(readmeTemplatesDir, 'README.template.md'), 'utf8')\nexport const DEFAULT_README_BODY = readFileSync(PATH.resolve(readmeTemplatesDir, 'README.body.md'), 'utf8')\n\nexport function applyLogoConfig(template: string, logoUrl?: string, logoLinkUrl?: string): string {\n let result = template\n if (logoUrl) {\n result = result.replace(/\\[logo]: .+/, `[logo]: ${logoUrl}`)\n if (logoLinkUrl) {\n result = result.replace(/\\[!\\[logo]\\[]][^)]*\\)/, `[![logo][]](${logoLinkUrl})`)\n }\n } else {\n result = result.replace(/\\[!\\[logo]\\[]][^\\n]*\\n*/, '')\n result = result.replace(/\\[logo]: [^\\n]*\\n?/, '')\n }\n return result\n}\n\nexport function resolveTemplatePath(templatePath: string | undefined): string {\n const cwd = INIT_CWD() ?? '.'\n return templatePath ?? PATH.join(cwd, '.xy', 'README.template.md')\n}\n\nasync function loadOrCreateTemplate(resolvedTemplatePath: string): Promise<{\n created: boolean\n template: string\n}> {\n try {\n const template = await readFile(resolvedTemplatePath, 'utf8')\n return { created: false, template }\n } catch {\n console.log(chalk.yellow(`Template not found: ${resolvedTemplatePath}`))\n const shouldCreate = await askConfirmation('Would you like to create a stock template? (y/N) ')\n if (!shouldCreate) {\n throw new Error('Template creation declined')\n }\n const template = DEFAULT_README_TEMPLATE\n await scaffoldTemplate(resolvedTemplatePath, template)\n return { created: true, template }\n }\n}\n\nexport async function scaffoldTemplate(resolvedTemplatePath: string, template: string): Promise<void> {\n const xyDir = PATH.dirname(resolvedTemplatePath)\n await mkdir(xyDir, { recursive: true })\n await writeFile(resolvedTemplatePath, template)\n console.log(chalk.green(`Created template: ${resolvedTemplatePath}`))\n const bodyPath = PATH.join(xyDir, 'README.body.md')\n await writeFile(bodyPath, DEFAULT_README_BODY)\n console.log(chalk.green(`Created body template: ${bodyPath}`))\n}\n\nasync function resolveBody(location: string, defaultBody: string): Promise<string> {\n const localBodyPath = PATH.join(location, 'README.body.md')\n try {\n return await readFile(localBodyPath, 'utf8')\n } catch {\n return defaultBody\n }\n}\n\nasync function generateReadmeForWorkspace(\n location: string,\n name: string,\n template: string,\n defaultBody: string,\n typedoc: boolean,\n verbose: boolean,\n): Promise<boolean> {\n try {\n const pkgJsonPath = PATH.join(location, 'package.json')\n const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf8'))\n const body = await resolveBody(location, defaultBody)\n const typedocContent = typedoc ? generateTypedoc(location, ['src/index*.ts']) : ''\n const readmeContent = fillTemplate(template, {\n ...pkgJson, body, typedoc: typedocContent,\n })\n await writeFile(PATH.join(location, 'README.md'), readmeContent)\n if (verbose) console.log(chalk.green(` ${name}`))\n return true\n } catch (ex) {\n const error = ex as Error\n console.warn(chalk.yellow(` Skipped ${location}: ${error.message}`))\n return false\n }\n}\n\nexport async function generateReadmeFiles({\n logoLinkUrl, logoUrl, pkg, templatePath, typedoc = false, verbose = false,\n}: GenerateReadmeFilesParams): Promise<number> {\n console.log(chalk.green('Generate README Files'))\n const resolvedTemplatePath = resolveTemplatePath(templatePath)\n\n let template: string\n let templateCreated: boolean\n try {\n ({ template, created: templateCreated } = await loadOrCreateTemplate(resolvedTemplatePath))\n } catch {\n return 1\n }\n\n template = applyLogoConfig(template, logoUrl, logoLinkUrl)\n\n if (templateCreated) {\n console.log(chalk.green('Generating README files for all packages...'))\n }\n\n const xyDir = PATH.dirname(resolvedTemplatePath)\n const xyBodyPath = PATH.join(xyDir, 'README.body.md')\n let defaultBody: string\n try {\n defaultBody = await readFile(xyBodyPath, 'utf8')\n } catch {\n defaultBody = DEFAULT_README_BODY\n }\n\n const workspaces = pkg && !templateCreated ? [yarnWorkspace(pkg)] : yarnWorkspaces()\n let failed = false\n\n for (const { location, name } of workspaces) {\n const success = await generateReadmeForWorkspace(location, name, template, defaultBody, typedoc, verbose)\n if (!success) failed = true\n }\n\n return failed ? 1 : 0\n}\n","import { spawnSync } from 'node:child_process'\n\nimport type { Workspace } from './Workspace.ts'\n\nexport const yarnWorkspaces = (): Workspace[] => {\n const result = spawnSync('yarn', ['workspaces', 'list', '--json', '--recursive'], { encoding: 'utf8', shell: true })\n if (result.error) {\n throw result.error\n }\n return (\n result.stdout\n .toString()\n // NOTE: This probably doesn't work on Windows\n // TODO: Replace /r/n with /n first\n .split('\\n')\n .slice(0, -1)\n .map((item) => {\n return JSON.parse(item)\n })\n )\n}\n","import type { Workspace } from './Workspace.ts'\nimport { yarnWorkspaces } from './yarnWorkspaces.ts'\n\nexport const yarnWorkspace = (pkg: string): Workspace => {\n const workspace = yarnWorkspaces().find(({ name }) => name === pkg)\n if (!workspace) throw new Error(`Workspace ${pkg} not found`)\n return workspace\n}\n","export const INIT_CWD = () => {\n if (!process.env.INIT_CWD) console.error('Missing INIT_CWD')\n return process.env.INIT_CWD\n}\n"],"mappings":"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","names":["require"]}
|
package/dist/lib/index.mjs
CHANGED
|
@@ -12,14 +12,19 @@ var checkResult = (name, result, level = "error", exitOnFail = false) => {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
// src/lib/claudeMdTemplate.ts
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
readdirSync,
|
|
17
|
+
readFileSync,
|
|
18
|
+
statSync
|
|
19
|
+
} from "fs";
|
|
16
20
|
import { createRequire } from "module";
|
|
17
21
|
import PATH from "path";
|
|
18
22
|
var require2 = createRequire(import.meta.url);
|
|
19
23
|
var packageRoot = PATH.dirname(require2.resolve("@xylabs/ts-scripts-yarn3/package.json"));
|
|
20
|
-
var templatesDir = PATH.resolve(packageRoot, "templates");
|
|
24
|
+
var templatesDir = PATH.resolve(packageRoot, "templates", "claude");
|
|
21
25
|
var XYLABS_RULES_PREFIX = "xylabs-";
|
|
22
26
|
var XYLABS_COMMANDS_PREFIX = "xylabs-";
|
|
27
|
+
var XYLABS_SKILLS_PREFIX = "xylabs-";
|
|
23
28
|
var claudeMdRuleTemplates = () => {
|
|
24
29
|
const rulesDir = PATH.resolve(templatesDir, "rules");
|
|
25
30
|
const files = readdirSync(rulesDir).filter((f) => f.startsWith(XYLABS_RULES_PREFIX) && f.endsWith(".md"));
|
|
@@ -38,6 +43,24 @@ var claudeCommandTemplates = () => {
|
|
|
38
43
|
}
|
|
39
44
|
return result;
|
|
40
45
|
};
|
|
46
|
+
var claudeSkillTemplates = () => {
|
|
47
|
+
const skillsDir = PATH.resolve(templatesDir, "skills");
|
|
48
|
+
const dirs = readdirSync(skillsDir).filter(
|
|
49
|
+
(f) => f.startsWith(XYLABS_SKILLS_PREFIX) && statSync(PATH.resolve(skillsDir, f)).isDirectory()
|
|
50
|
+
);
|
|
51
|
+
const result = {};
|
|
52
|
+
for (const dir of dirs) {
|
|
53
|
+
const dirPath = PATH.resolve(skillsDir, dir);
|
|
54
|
+
const files = readdirSync(dirPath, { recursive: true, encoding: "utf8" });
|
|
55
|
+
result[dir] = {};
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
if (statSync(PATH.resolve(dirPath, file)).isFile()) {
|
|
58
|
+
result[dir][file] = readFileSync(PATH.resolve(dirPath, file), "utf8");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
};
|
|
41
64
|
var claudeMdProjectTemplate = () => readFileSync(PATH.resolve(templatesDir, "CLAUDE-project.md"), "utf8");
|
|
42
65
|
|
|
43
66
|
// src/lib/createBuildConfig.ts
|
|
@@ -378,10 +401,19 @@ var generateIgnoreFiles = (filename, pkg) => {
|
|
|
378
401
|
|
|
379
402
|
// src/lib/generateReadmeFiles.ts
|
|
380
403
|
import { execSync as execSync2 } from "child_process";
|
|
381
|
-
import FS from "fs";
|
|
382
|
-
import {
|
|
404
|
+
import FS, { readFileSync as readFileSync5 } from "fs";
|
|
405
|
+
import {
|
|
406
|
+
mkdir,
|
|
407
|
+
readFile,
|
|
408
|
+
writeFile
|
|
409
|
+
} from "fs/promises";
|
|
410
|
+
import { createRequire as createRequire2 } from "module";
|
|
383
411
|
import PATH2 from "path";
|
|
412
|
+
import { createInterface } from "readline";
|
|
384
413
|
import chalk5 from "chalk";
|
|
414
|
+
var require3 = createRequire2(import.meta.url);
|
|
415
|
+
var packageRoot2 = PATH2.dirname(require3.resolve("@xylabs/ts-scripts-yarn3/package.json"));
|
|
416
|
+
var readmeTemplatesDir = PATH2.resolve(packageRoot2, "templates", "readme");
|
|
385
417
|
function fillTemplate(template, data) {
|
|
386
418
|
const additionalData = { ...data, safeName: data.name.replaceAll("/", "__").replaceAll("@", "") };
|
|
387
419
|
return template.replaceAll(/\{\{(.*?)\}\}/g, (_, key) => additionalData[key.trim()] ?? "");
|
|
@@ -471,37 +503,120 @@ ${indent}### ${item.name}
|
|
|
471
503
|
}
|
|
472
504
|
return content;
|
|
473
505
|
}
|
|
506
|
+
function askConfirmation(question) {
|
|
507
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
508
|
+
return new Promise((resolve) => {
|
|
509
|
+
rl.question(question, (answer) => {
|
|
510
|
+
rl.close();
|
|
511
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
var DEFAULT_README_TEMPLATE = readFileSync5(PATH2.resolve(readmeTemplatesDir, "README.template.md"), "utf8");
|
|
516
|
+
var DEFAULT_README_BODY = readFileSync5(PATH2.resolve(readmeTemplatesDir, "README.body.md"), "utf8");
|
|
517
|
+
function applyLogoConfig(template, logoUrl, logoLinkUrl) {
|
|
518
|
+
let result = template;
|
|
519
|
+
if (logoUrl) {
|
|
520
|
+
result = result.replace(/\[logo]: .+/, `[logo]: ${logoUrl}`);
|
|
521
|
+
if (logoLinkUrl) {
|
|
522
|
+
result = result.replace(/\[!\[logo]\[]][^)]*\)/, `[![logo][]](${logoLinkUrl})`);
|
|
523
|
+
}
|
|
524
|
+
} else {
|
|
525
|
+
result = result.replace(/\[!\[logo]\[]][^\n]*\n*/, "");
|
|
526
|
+
result = result.replace(/\[logo]: [^\n]*\n?/, "");
|
|
527
|
+
}
|
|
528
|
+
return result;
|
|
529
|
+
}
|
|
530
|
+
function resolveTemplatePath(templatePath) {
|
|
531
|
+
const cwd = INIT_CWD() ?? ".";
|
|
532
|
+
return templatePath ?? PATH2.join(cwd, ".xy", "README.template.md");
|
|
533
|
+
}
|
|
534
|
+
async function loadOrCreateTemplate(resolvedTemplatePath) {
|
|
535
|
+
try {
|
|
536
|
+
const template = await readFile(resolvedTemplatePath, "utf8");
|
|
537
|
+
return { created: false, template };
|
|
538
|
+
} catch {
|
|
539
|
+
console.log(chalk5.yellow(`Template not found: ${resolvedTemplatePath}`));
|
|
540
|
+
const shouldCreate = await askConfirmation("Would you like to create a stock template? (y/N) ");
|
|
541
|
+
if (!shouldCreate) {
|
|
542
|
+
throw new Error("Template creation declined");
|
|
543
|
+
}
|
|
544
|
+
const template = DEFAULT_README_TEMPLATE;
|
|
545
|
+
await scaffoldTemplate(resolvedTemplatePath, template);
|
|
546
|
+
return { created: true, template };
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
async function scaffoldTemplate(resolvedTemplatePath, template) {
|
|
550
|
+
const xyDir = PATH2.dirname(resolvedTemplatePath);
|
|
551
|
+
await mkdir(xyDir, { recursive: true });
|
|
552
|
+
await writeFile(resolvedTemplatePath, template);
|
|
553
|
+
console.log(chalk5.green(`Created template: ${resolvedTemplatePath}`));
|
|
554
|
+
const bodyPath = PATH2.join(xyDir, "README.body.md");
|
|
555
|
+
await writeFile(bodyPath, DEFAULT_README_BODY);
|
|
556
|
+
console.log(chalk5.green(`Created body template: ${bodyPath}`));
|
|
557
|
+
}
|
|
558
|
+
async function resolveBody(location, defaultBody) {
|
|
559
|
+
const localBodyPath = PATH2.join(location, "README.body.md");
|
|
560
|
+
try {
|
|
561
|
+
return await readFile(localBodyPath, "utf8");
|
|
562
|
+
} catch {
|
|
563
|
+
return defaultBody;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
async function generateReadmeForWorkspace(location, name, template, defaultBody, typedoc, verbose) {
|
|
567
|
+
try {
|
|
568
|
+
const pkgJsonPath = PATH2.join(location, "package.json");
|
|
569
|
+
const pkgJson = JSON.parse(await readFile(pkgJsonPath, "utf8"));
|
|
570
|
+
const body = await resolveBody(location, defaultBody);
|
|
571
|
+
const typedocContent = typedoc ? generateTypedoc(location, ["src/index*.ts"]) : "";
|
|
572
|
+
const readmeContent = fillTemplate(template, {
|
|
573
|
+
...pkgJson,
|
|
574
|
+
body,
|
|
575
|
+
typedoc: typedocContent
|
|
576
|
+
});
|
|
577
|
+
await writeFile(PATH2.join(location, "README.md"), readmeContent);
|
|
578
|
+
if (verbose) console.log(chalk5.green(` ${name}`));
|
|
579
|
+
return true;
|
|
580
|
+
} catch (ex) {
|
|
581
|
+
const error = ex;
|
|
582
|
+
console.warn(chalk5.yellow(` Skipped ${location}: ${error.message}`));
|
|
583
|
+
return false;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
474
586
|
async function generateReadmeFiles({
|
|
587
|
+
logoLinkUrl,
|
|
588
|
+
logoUrl,
|
|
475
589
|
pkg,
|
|
476
590
|
templatePath,
|
|
477
591
|
typedoc = false,
|
|
478
|
-
verbose
|
|
592
|
+
verbose = false
|
|
479
593
|
}) {
|
|
480
594
|
console.log(chalk5.green("Generate README Files"));
|
|
481
|
-
const
|
|
482
|
-
const resolvedTemplatePath = templatePath ?? PATH2.join(cwd, "scripts", "README.template.md");
|
|
595
|
+
const resolvedTemplatePath = resolveTemplatePath(templatePath);
|
|
483
596
|
let template;
|
|
597
|
+
let templateCreated;
|
|
484
598
|
try {
|
|
485
|
-
template = await
|
|
599
|
+
({ template, created: templateCreated } = await loadOrCreateTemplate(resolvedTemplatePath));
|
|
486
600
|
} catch {
|
|
487
|
-
console.error(chalk5.red(`Template not found: ${resolvedTemplatePath}`));
|
|
488
601
|
return 1;
|
|
489
602
|
}
|
|
490
|
-
|
|
603
|
+
template = applyLogoConfig(template, logoUrl, logoLinkUrl);
|
|
604
|
+
if (templateCreated) {
|
|
605
|
+
console.log(chalk5.green("Generating README files for all packages..."));
|
|
606
|
+
}
|
|
607
|
+
const xyDir = PATH2.dirname(resolvedTemplatePath);
|
|
608
|
+
const xyBodyPath = PATH2.join(xyDir, "README.body.md");
|
|
609
|
+
let defaultBody;
|
|
610
|
+
try {
|
|
611
|
+
defaultBody = await readFile(xyBodyPath, "utf8");
|
|
612
|
+
} catch {
|
|
613
|
+
defaultBody = DEFAULT_README_BODY;
|
|
614
|
+
}
|
|
615
|
+
const workspaces = pkg && !templateCreated ? [yarnWorkspace(pkg)] : yarnWorkspaces();
|
|
491
616
|
let failed = false;
|
|
492
617
|
for (const { location, name } of workspaces) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const pkgJson = JSON.parse(await readFile(pkgJsonPath, "utf8"));
|
|
496
|
-
const typedocContent = typedoc ? generateTypedoc(location, ["src/index*.ts"]) : "";
|
|
497
|
-
const readmeContent = fillTemplate(template, { ...pkgJson, typedoc: typedocContent });
|
|
498
|
-
await writeFile(PATH2.join(location, "README.md"), readmeContent);
|
|
499
|
-
if (verbose) console.log(chalk5.green(` ${name}`));
|
|
500
|
-
} catch (ex) {
|
|
501
|
-
const error = ex;
|
|
502
|
-
console.warn(chalk5.yellow(` Skipped ${location}: ${error.message}`));
|
|
503
|
-
failed = true;
|
|
504
|
-
}
|
|
618
|
+
const success = await generateReadmeForWorkspace(location, name, template, defaultBody, typedoc, verbose);
|
|
619
|
+
if (!success) failed = true;
|
|
505
620
|
}
|
|
506
621
|
return failed ? 1 : 0;
|
|
507
622
|
}
|
|
@@ -528,10 +643,10 @@ var loadConfig = async (params) => {
|
|
|
528
643
|
};
|
|
529
644
|
|
|
530
645
|
// src/lib/parsedPackageJSON.ts
|
|
531
|
-
import { readFileSync as
|
|
646
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
532
647
|
var parsedPackageJSON = (path) => {
|
|
533
648
|
const pathToPackageJSON = path ?? process.env.npm_package_json ?? "";
|
|
534
|
-
const packageJSON =
|
|
649
|
+
const packageJSON = readFileSync6(pathToPackageJSON).toString();
|
|
535
650
|
return JSON.parse(packageJSON);
|
|
536
651
|
};
|
|
537
652
|
|
|
@@ -633,15 +748,20 @@ var runXyWithWarning = (command) => {
|
|
|
633
748
|
};
|
|
634
749
|
export {
|
|
635
750
|
CROSS_PLATFORM_NEWLINE,
|
|
751
|
+
DEFAULT_README_BODY,
|
|
752
|
+
DEFAULT_README_TEMPLATE,
|
|
636
753
|
DuplicateDetector,
|
|
637
754
|
INIT_CWD,
|
|
638
755
|
WINDOWS_NEWLINE_REGEX,
|
|
639
756
|
XYLABS_COMMANDS_PREFIX,
|
|
640
757
|
XYLABS_RULES_PREFIX,
|
|
758
|
+
XYLABS_SKILLS_PREFIX,
|
|
759
|
+
applyLogoConfig,
|
|
641
760
|
checkResult,
|
|
642
761
|
claudeCommandTemplates,
|
|
643
762
|
claudeMdProjectTemplate,
|
|
644
763
|
claudeMdRuleTemplates,
|
|
764
|
+
claudeSkillTemplates,
|
|
645
765
|
createBuildConfig,
|
|
646
766
|
defaultBuildConfig,
|
|
647
767
|
defaultReadFileSyncOptions,
|
|
@@ -658,6 +778,7 @@ export {
|
|
|
658
778
|
processEx,
|
|
659
779
|
readLines,
|
|
660
780
|
readNonEmptyLines,
|
|
781
|
+
resolveTemplatePath,
|
|
661
782
|
runStepAsync,
|
|
662
783
|
runSteps,
|
|
663
784
|
runStepsAsync,
|
|
@@ -665,6 +786,7 @@ export {
|
|
|
665
786
|
runXyWithWarning,
|
|
666
787
|
safeExit,
|
|
667
788
|
safeExitAsync,
|
|
789
|
+
scaffoldTemplate,
|
|
668
790
|
tryReadFileSync,
|
|
669
791
|
union,
|
|
670
792
|
withErrnoException,
|