readme-cli-gen 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,7 @@
20
20
  </a>
21
21
  <img src="https://img.shields.io/static/v1?label=License&message=MIT&color=0000ff&style=for-the-badge" alt="License">
22
22
  <a href="https://www.npmjs.com/package/readme-cli-gen">
23
- <img src="https://img.shields.io/npm/v/readme-cli-gen?style=for-the-badge" alt="npm version">
23
+ <img src="https://img.shields.io/npm/v/readme-cli-gen?style=for-the-badge&cacheBust=1" alt="npm version">
24
24
  </a>
25
25
  </p>
26
26
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=detector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/detector.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,234 @@
1
+ import { execSync } from "child_process";
2
+ import fs from "fs";
3
+ import os from "os";
4
+ import path from "path";
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+ import { detectProject } from "../detector.js";
7
+ // vi.mock is hoisted — intercepts child_process before detector.ts imports it
8
+ vi.mock("child_process", () => ({
9
+ execSync: vi.fn(),
10
+ }));
11
+ // ---------------------------------------------------------------------------
12
+ // Helpers
13
+ // ---------------------------------------------------------------------------
14
+ function makeTmpDir() {
15
+ return fs.mkdtempSync(path.join(os.tmpdir(), "readme-gen-test-"));
16
+ }
17
+ function writeJson(dir, filename, content) {
18
+ fs.writeFileSync(path.join(dir, filename), JSON.stringify(content));
19
+ }
20
+ function writeFile(dir, filename, content) {
21
+ fs.writeFileSync(path.join(dir, filename), content);
22
+ }
23
+ // ---------------------------------------------------------------------------
24
+ // Setup / teardown
25
+ // ---------------------------------------------------------------------------
26
+ let tmpDir;
27
+ beforeEach(() => {
28
+ tmpDir = makeTmpDir();
29
+ vi.spyOn(console, "warn").mockImplementation(() => { });
30
+ // Default: git commands are unavailable
31
+ vi.mocked(execSync).mockImplementation(() => {
32
+ throw new Error("no git");
33
+ });
34
+ });
35
+ afterEach(() => {
36
+ fs.rmSync(tmpDir, { recursive: true, force: true });
37
+ vi.clearAllMocks();
38
+ });
39
+ // ---------------------------------------------------------------------------
40
+ // package.json parsing
41
+ // ---------------------------------------------------------------------------
42
+ describe("detectProject — package.json", () => {
43
+ it("reads name, description, license from package.json", () => {
44
+ writeJson(tmpDir, "package.json", {
45
+ name: "my-app",
46
+ description: "A test app",
47
+ license: "MIT",
48
+ });
49
+ const info = detectProject(tmpDir);
50
+ expect(info.name).toBe("my-app");
51
+ expect(info.description).toBe("A test app");
52
+ expect(info.license).toBe("MIT");
53
+ });
54
+ it("reads author as string from package.json", () => {
55
+ writeJson(tmpDir, "package.json", { author: "Alice" });
56
+ const info = detectProject(tmpDir);
57
+ expect(info.author).toBe("Alice");
58
+ });
59
+ it("reads author.name when author is an object", () => {
60
+ writeJson(tmpDir, "package.json", { author: { name: "Bob", email: "bob@example.com" } });
61
+ const info = detectProject(tmpDir);
62
+ expect(info.author).toBe("Bob");
63
+ });
64
+ it("reads scripts, dependencies, devDependencies", () => {
65
+ writeJson(tmpDir, "package.json", {
66
+ scripts: { start: "node index.js" },
67
+ dependencies: { express: "^4.0.0" },
68
+ devDependencies: { typescript: "^5.0.0" },
69
+ });
70
+ const info = detectProject(tmpDir);
71
+ expect(info.scripts?.["start"]).toBe("node index.js");
72
+ expect(info.dependencies?.["express"]).toBe("^4.0.0");
73
+ expect(info.devDependencies?.["typescript"]).toBe("^5.0.0");
74
+ });
75
+ it("returns empty ProjectInfo when directory has no package.json", () => {
76
+ const info = detectProject(tmpDir);
77
+ expect(info.name).toBeUndefined();
78
+ expect(info.description).toBeUndefined();
79
+ });
80
+ });
81
+ // ---------------------------------------------------------------------------
82
+ // LICENSE file detection
83
+ // ---------------------------------------------------------------------------
84
+ describe("detectProject — LICENSE file", () => {
85
+ it("detects MIT from LICENSE file content when package.json has no license", () => {
86
+ writeJson(tmpDir, "package.json", { name: "app" });
87
+ writeFile(tmpDir, "LICENSE", "MIT License\nCopyright...");
88
+ const info = detectProject(tmpDir);
89
+ expect(info.license).toBe("MIT");
90
+ });
91
+ it("detects Apache 2.0 from LICENSE file", () => {
92
+ writeJson(tmpDir, "package.json", { name: "app" });
93
+ writeFile(tmpDir, "LICENSE", "Apache License Version 2.0");
94
+ const info = detectProject(tmpDir);
95
+ expect(info.license).toBe("Apache 2.0");
96
+ });
97
+ it("detects GPL from LICENSE file", () => {
98
+ writeJson(tmpDir, "package.json", { name: "app" });
99
+ writeFile(tmpDir, "LICENSE", "GNU GPL v3");
100
+ const info = detectProject(tmpDir);
101
+ expect(info.license).toBe("GPL");
102
+ });
103
+ it("detects BSD from LICENSE file", () => {
104
+ writeJson(tmpDir, "package.json", { name: "app" });
105
+ writeFile(tmpDir, "LICENSE", "BSD 2-Clause License");
106
+ const info = detectProject(tmpDir);
107
+ expect(info.license).toBe("BSD");
108
+ });
109
+ it("prefers license from package.json over LICENSE file", () => {
110
+ writeJson(tmpDir, "package.json", { license: "ISC" });
111
+ writeFile(tmpDir, "LICENSE", "MIT License");
112
+ const info = detectProject(tmpDir);
113
+ expect(info.license).toBe("ISC");
114
+ });
115
+ });
116
+ // ---------------------------------------------------------------------------
117
+ // .env.example parsing
118
+ // ---------------------------------------------------------------------------
119
+ describe("detectProject — .env.example", () => {
120
+ it("extracts variable names from .env.example", () => {
121
+ writeFile(tmpDir, ".env.example", "DATABASE_URL=\nAPI_KEY=secret\n");
122
+ const info = detectProject(tmpDir);
123
+ expect(info.envVars).toContain("DATABASE_URL");
124
+ expect(info.envVars).toContain("API_KEY");
125
+ });
126
+ it("ignores comment lines in .env.example", () => {
127
+ writeFile(tmpDir, ".env.example", "# This is a comment\nPORT=3000\n");
128
+ const info = detectProject(tmpDir);
129
+ expect(info.envVars).not.toContain("# This is a comment");
130
+ expect(info.envVars).toContain("PORT");
131
+ });
132
+ it("ignores empty lines in .env.example", () => {
133
+ writeFile(tmpDir, ".env.example", "\nAPI_KEY=\n\n");
134
+ const info = detectProject(tmpDir);
135
+ expect(info.envVars).toEqual(["API_KEY"]);
136
+ });
137
+ });
138
+ // ---------------------------------------------------------------------------
139
+ // Dockerfile detection
140
+ // ---------------------------------------------------------------------------
141
+ describe("detectProject — Dockerfile", () => {
142
+ it("sets hasDocker to true when Dockerfile exists", () => {
143
+ writeFile(tmpDir, "Dockerfile", "FROM node:20\nEXPOSE 3000\n");
144
+ const info = detectProject(tmpDir);
145
+ expect(info.hasDocker).toBe(true);
146
+ });
147
+ it("extracts the exposed port from Dockerfile", () => {
148
+ writeFile(tmpDir, "Dockerfile", "FROM node:20\nEXPOSE 8080\n");
149
+ const info = detectProject(tmpDir);
150
+ expect(info.dockerPort).toBe("8080");
151
+ });
152
+ it("sets hasDocker true with no port when EXPOSE is absent", () => {
153
+ writeFile(tmpDir, "Dockerfile", "FROM node:20\nRUN npm install\n");
154
+ const info = detectProject(tmpDir);
155
+ expect(info.hasDocker).toBe(true);
156
+ expect(info.dockerPort).toBeUndefined();
157
+ });
158
+ it("does not set hasDocker when Dockerfile is absent", () => {
159
+ const info = detectProject(tmpDir);
160
+ expect(info.hasDocker).toBeUndefined();
161
+ });
162
+ });
163
+ // ---------------------------------------------------------------------------
164
+ // Git integration
165
+ // ---------------------------------------------------------------------------
166
+ describe("detectProject — git", () => {
167
+ it("uses git user.name as author fallback when package.json has no author", () => {
168
+ writeJson(tmpDir, "package.json", { name: "app" });
169
+ vi.mocked(execSync).mockImplementation((cmd) => {
170
+ if (String(cmd).includes("user.name"))
171
+ return Buffer.from("Git User\n");
172
+ throw new Error("no remote");
173
+ });
174
+ const info = detectProject(tmpDir);
175
+ expect(info.author).toBe("Git User");
176
+ });
177
+ it("does not override package.json author with git user.name", () => {
178
+ writeJson(tmpDir, "package.json", { author: "Package Author" });
179
+ vi.mocked(execSync).mockImplementation((cmd) => {
180
+ if (String(cmd).includes("user.name"))
181
+ return Buffer.from("Git User\n");
182
+ throw new Error("no remote");
183
+ });
184
+ const info = detectProject(tmpDir);
185
+ expect(info.author).toBe("Package Author");
186
+ });
187
+ it("extracts GitHub username from HTTPS remote URL", () => {
188
+ vi.mocked(execSync).mockImplementation((cmd) => {
189
+ if (String(cmd).includes("user.name"))
190
+ return Buffer.from("Alice\n");
191
+ if (String(cmd).includes("remote.origin.url"))
192
+ return Buffer.from("https://github.com/alice/my-repo.git\n");
193
+ throw new Error("unknown");
194
+ });
195
+ const info = detectProject(tmpDir);
196
+ expect(info.githubUser).toBe("alice");
197
+ });
198
+ it("extracts GitHub username from SSH remote URL", () => {
199
+ vi.mocked(execSync).mockImplementation((cmd) => {
200
+ if (String(cmd).includes("user.name"))
201
+ throw new Error("no user");
202
+ if (String(cmd).includes("remote.origin.url"))
203
+ return Buffer.from("git@github.com:alice/my-repo.git\n");
204
+ throw new Error("unknown");
205
+ });
206
+ const info = detectProject(tmpDir);
207
+ expect(info.githubUser).toBe("alice");
208
+ });
209
+ it("returns undefined githubUser when git remote is unavailable", () => {
210
+ const info = detectProject(tmpDir);
211
+ expect(info.githubUser).toBeUndefined();
212
+ });
213
+ });
214
+ // ---------------------------------------------------------------------------
215
+ // Test script detection
216
+ // ---------------------------------------------------------------------------
217
+ describe("detectProject — test command", () => {
218
+ it("detects 'test' script from package.json", () => {
219
+ writeJson(tmpDir, "package.json", { scripts: { test: "vitest run" } });
220
+ const info = detectProject(tmpDir);
221
+ expect(info.testCommand).toBe("npm run test");
222
+ });
223
+ it("detects 'test:unit' script from package.json", () => {
224
+ writeJson(tmpDir, "package.json", { scripts: { "test:unit": "vitest run" } });
225
+ const info = detectProject(tmpDir);
226
+ expect(info.testCommand).toBe("npm run test:unit");
227
+ });
228
+ it("returns undefined testCommand when no test script exists", () => {
229
+ writeJson(tmpDir, "package.json", { scripts: { start: "node index.js" } });
230
+ const info = detectProject(tmpDir);
231
+ expect(info.testCommand).toBeUndefined();
232
+ });
233
+ });
234
+ //# sourceMappingURL=detector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.test.js","sourceRoot":"","sources":["../../src/__tests__/detector.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=template.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/template.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,168 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildContributorsTable, buildTableOfContents, detectMissingFields, fillTemplate, } from "../template.js";
3
+ // ---------------------------------------------------------------------------
4
+ // fillTemplate
5
+ // ---------------------------------------------------------------------------
6
+ describe("fillTemplate", () => {
7
+ it("replaces {{key}} placeholders with data values", () => {
8
+ const result = fillTemplate("Hello {{name}}!", { project_name: "world", name: "world" });
9
+ expect(result).toBe("Hello world!");
10
+ });
11
+ it("leaves unknown placeholders untouched", () => {
12
+ const result = fillTemplate("Hello {{unknown}}!", {});
13
+ expect(result).toBe("Hello {{unknown}}!");
14
+ });
15
+ it("renders {{#if key}}...{{/if}} block when key is present", () => {
16
+ const result = fillTemplate("{{#if has_docker}}Docker section{{/if}}", {
17
+ has_docker: "true",
18
+ });
19
+ expect(result).toBe("Docker section");
20
+ });
21
+ it("removes {{#if key}}...{{/if}} block when key is absent", () => {
22
+ const result = fillTemplate("before{{#if has_docker}}Docker section{{/if}}after", {});
23
+ expect(result).toBe("beforeafter");
24
+ });
25
+ it("substitutes extras values", () => {
26
+ const result = fillTemplate("Value: {{custom}}", {}, { custom: "hello" });
27
+ expect(result).toBe("Value: hello");
28
+ });
29
+ it("extras override data for the same key", () => {
30
+ const result = fillTemplate("{{description}}", { description: "original" }, { description: "overridden" });
31
+ expect(result).toBe("overridden");
32
+ });
33
+ it("replaces all occurrences of the same placeholder", () => {
34
+ const result = fillTemplate("{{name}} and {{name}}", { project_name: "x", name: "x" });
35
+ expect(result).toBe("x and x");
36
+ });
37
+ });
38
+ // ---------------------------------------------------------------------------
39
+ // detectMissingFields
40
+ // ---------------------------------------------------------------------------
41
+ describe("detectMissingFields", () => {
42
+ it("returns empty array when all fields are present", () => {
43
+ const missing = detectMissingFields("{{name}} {{description}}", {
44
+ project_name: "x",
45
+ name: "x",
46
+ description: "y",
47
+ });
48
+ expect(missing).toEqual([]);
49
+ });
50
+ it("returns field names missing from data", () => {
51
+ const missing = detectMissingFields("{{name}} {{missing_field}}", {
52
+ project_name: "x",
53
+ name: "x",
54
+ });
55
+ expect(missing).toEqual(["missing_field"]);
56
+ });
57
+ it("ignores the 'if' keyword from conditional blocks", () => {
58
+ const missing = detectMissingFields("{{#if has_docker}}text{{/if}}", {});
59
+ expect(missing).not.toContain("if");
60
+ });
61
+ it("deduplicates repeated field names", () => {
62
+ const missing = detectMissingFields("{{foo}} {{foo}} {{foo}}", {});
63
+ expect(missing).toEqual(["foo"]);
64
+ });
65
+ it("does not list fields that are present in data", () => {
66
+ const missing = detectMissingFields("{{description}}", { description: "hello" });
67
+ expect(missing).toEqual([]);
68
+ });
69
+ });
70
+ // ---------------------------------------------------------------------------
71
+ // buildContributorsTable
72
+ // ---------------------------------------------------------------------------
73
+ describe("buildContributorsTable", () => {
74
+ it("returns an HTML table", () => {
75
+ const result = buildContributorsTable("Alice--alice");
76
+ expect(result).toContain("<table>");
77
+ expect(result).toContain("</table>");
78
+ });
79
+ it("creates a cell with github avatar and link for each contributor", () => {
80
+ const result = buildContributorsTable("Alice--alice");
81
+ expect(result).toContain("https://github.com/alice");
82
+ expect(result).toContain("https://avatars.githubusercontent.com/alice");
83
+ expect(result).toContain("Alice");
84
+ });
85
+ it("fits up to 3 contributors in a single row", () => {
86
+ const input = "A--a\nB--b\nC--c";
87
+ const result = buildContributorsTable(input);
88
+ const rowCount = (result.match(/<tr>/g) ?? []).length;
89
+ expect(rowCount).toBe(1);
90
+ });
91
+ it("wraps a 4th contributor into a second row", () => {
92
+ const input = "A--a\nB--b\nC--c\nD--d";
93
+ const result = buildContributorsTable(input);
94
+ const rowCount = (result.match(/<tr>/g) ?? []).length;
95
+ expect(rowCount).toBe(2);
96
+ });
97
+ it("ignores lines without the -- separator", () => {
98
+ const result = buildContributorsTable("invalid line\nAlice--alice");
99
+ expect(result).toContain("alice");
100
+ expect(result).not.toContain("invalid");
101
+ });
102
+ it("trims whitespace from name and username", () => {
103
+ const result = buildContributorsTable(" Alice -- alice ");
104
+ expect(result).toContain(">Alice<");
105
+ expect(result).toContain("github.com/alice");
106
+ });
107
+ });
108
+ // ---------------------------------------------------------------------------
109
+ // buildTableOfContents
110
+ // ---------------------------------------------------------------------------
111
+ describe("buildTableOfContents", () => {
112
+ it("always includes base sections", () => {
113
+ const toc = buildTableOfContents({});
114
+ expect(toc).toContain("About the Project");
115
+ expect(toc).toContain("Installation");
116
+ expect(toc).toContain("Contributing");
117
+ });
118
+ it("includes Usage subsection when usage_command is set", () => {
119
+ const toc = buildTableOfContents({ usage_command: "npm start" });
120
+ expect(toc).toContain("Usage");
121
+ });
122
+ it("omits Usage subsection when usage_command is absent", () => {
123
+ const toc = buildTableOfContents({});
124
+ expect(toc).not.toContain("Usage");
125
+ });
126
+ it("includes Environment Variables when env_vars is set", () => {
127
+ const toc = buildTableOfContents({ env_vars: "DATABASE_URL" });
128
+ expect(toc).toContain("Environment Variables");
129
+ });
130
+ it("omits Environment Variables when env_vars is absent", () => {
131
+ const toc = buildTableOfContents({});
132
+ expect(toc).not.toContain("Environment Variables");
133
+ });
134
+ it("includes Docker section when has_docker is set", () => {
135
+ const toc = buildTableOfContents({ has_docker: "true" });
136
+ expect(toc).toContain("Docker");
137
+ });
138
+ it("omits Docker section when has_docker is absent", () => {
139
+ const toc = buildTableOfContents({});
140
+ expect(toc).not.toContain("Docker");
141
+ });
142
+ it("includes Contributors when contributors_table is set", () => {
143
+ const toc = buildTableOfContents({ contributors_table: "<table></table>" });
144
+ expect(toc).toContain("Contributors");
145
+ });
146
+ it("includes License when license is set", () => {
147
+ const toc = buildTableOfContents({ license: "MIT" });
148
+ expect(toc).toContain("License");
149
+ });
150
+ it("includes Author when author is set", () => {
151
+ const toc = buildTableOfContents({ author: "Alice" });
152
+ expect(toc).toContain("Author");
153
+ });
154
+ it("omits License and Author when not set", () => {
155
+ const toc = buildTableOfContents({});
156
+ expect(toc).not.toContain("License");
157
+ expect(toc).not.toContain("Author");
158
+ });
159
+ it("includes Running Tests when test_command is set", () => {
160
+ const toc = buildTableOfContents({ test_command: "npm test" });
161
+ expect(toc).toContain("Running Tests");
162
+ });
163
+ it("omits Running Tests when test_command is absent", () => {
164
+ const toc = buildTableOfContents({});
165
+ expect(toc).not.toContain("Running Tests");
166
+ });
167
+ });
168
+ //# sourceMappingURL=template.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.test.js","sourceRoot":"","sources":["../../src/__tests__/template.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAW,CAAC,CAAC;QAClG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,MAAM,GAAG,YAAY,CAAC,yCAAyC,EAAE;YACrE,UAAU,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,YAAY,CAAC,oDAAoD,EAAE,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,YAAY,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,MAAM,GAAG,YAAY,CACzB,iBAAiB,EACjB,EAAE,WAAW,EAAE,UAAU,EAAE,EAC3B,EAAE,WAAW,EAAE,YAAY,EAAE,CAC9B,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,YAAY,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC,CAAC;QAChG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,OAAO,GAAG,mBAAmB,CAAC,0BAA0B,EAAE;YAC9D,YAAY,EAAE,GAAG;YACjB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,GAAG;SACR,CAAC,CAAC;QACZ,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG,mBAAmB,CAAC,4BAA4B,EAAE;YAChE,YAAY,EAAE,GAAG;YACjB,IAAI,EAAE,GAAG;SACD,CAAC,CAAC;QACZ,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,OAAO,GAAG,mBAAmB,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,mBAAmB,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,OAAO,GAAG,mBAAmB,CAAC,iBAAiB,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QACjF,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,MAAM,GAAG,sBAAsB,CAAC,cAAc,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,MAAM,GAAG,sBAAsB,CAAC,cAAc,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,6CAA6C,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,KAAK,GAAG,kBAAkB,CAAC;QACjC,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACtD,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,KAAK,GAAG,wBAAwB,CAAC;QACvC,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACtD,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,sBAAsB,CAAC,4BAA4B,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,sBAAsB,CAAC,sBAAsB,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface ProjectInfo {
2
+ name?: string;
3
+ description?: string;
4
+ author?: string;
5
+ githubUser?: string;
6
+ license?: string;
7
+ scripts?: Record<string, string>;
8
+ dependencies?: Record<string, string>;
9
+ devDependencies?: Record<string, string>;
10
+ envVars?: string[];
11
+ dockerPort?: string;
12
+ hasDocker?: boolean;
13
+ testCommand?: string;
14
+ }
15
+ export declare function detectProject(projectPath: string): ProjectInfo;
16
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAmF9D"}
@@ -0,0 +1,88 @@
1
+ import { execSync } from "child_process";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ export function detectProject(projectPath) {
5
+ const info = {};
6
+ const pkgPath = path.join(projectPath, "package.json");
7
+ if (fs.existsSync(pkgPath)) {
8
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
9
+ info.name = pkg.name;
10
+ info.description = pkg.description;
11
+ info.license = pkg.license;
12
+ info.scripts = pkg.scripts;
13
+ info.dependencies = pkg.dependencies;
14
+ info.devDependencies = pkg.devDependencies;
15
+ if (typeof pkg.author === "string")
16
+ info.author = pkg.author;
17
+ else if (pkg.author?.name)
18
+ info.author = pkg.author.name;
19
+ }
20
+ // Search for license in LICENSE file if not found in package.json
21
+ if (!info.license) {
22
+ const licenseFiles = ["LICENSE", "LICENSE.md", "LICENSE.txt"];
23
+ for (const file of licenseFiles) {
24
+ const licensePath = path.join(projectPath, file);
25
+ if (fs.existsSync(licensePath)) {
26
+ const content = fs.readFileSync(licensePath, "utf-8");
27
+ if (content.includes("MIT"))
28
+ info.license = "MIT";
29
+ else if (content.includes("Apache"))
30
+ info.license = "Apache 2.0";
31
+ else if (content.includes("GPL"))
32
+ info.license = "GPL";
33
+ else if (content.includes("BSD"))
34
+ info.license = "BSD";
35
+ else
36
+ info.license = file;
37
+ break;
38
+ }
39
+ }
40
+ }
41
+ try {
42
+ const gitUser = execSync("git config user.name", {
43
+ cwd: projectPath,
44
+ stdio: "pipe",
45
+ })
46
+ .toString()
47
+ .trim();
48
+ if (gitUser && !info.author)
49
+ info.author = gitUser;
50
+ }
51
+ catch (error) {
52
+ console.warn("Could not read user.name from git:", error);
53
+ }
54
+ try {
55
+ const remoteUrl = execSync("git config remote.origin.url", {
56
+ cwd: projectPath,
57
+ stdio: "pipe",
58
+ })
59
+ .toString()
60
+ .trim();
61
+ const match = remoteUrl.match(/github\.com[:/]([^/]+)\//);
62
+ if (match?.[1])
63
+ info.githubUser = match[1];
64
+ }
65
+ catch (error) {
66
+ console.warn("Could not read remote.origin.url from git:", error);
67
+ }
68
+ const envPath = path.join(projectPath, ".env.example");
69
+ if (fs.existsSync(envPath)) {
70
+ const lines = fs.readFileSync(envPath, "utf-8").split("\n");
71
+ info.envVars = lines
72
+ .filter((l) => l.trim() && !l.startsWith("#"))
73
+ .map((l) => l.split("=")[0]?.trim() ?? l.trim());
74
+ }
75
+ const testScript = Object.keys(info.scripts ?? {}).find((s) => s === "test" || s.startsWith("test:"));
76
+ if (testScript)
77
+ info.testCommand = `npm run ${testScript}`;
78
+ const dockerfilePath = path.join(projectPath, "Dockerfile");
79
+ if (fs.existsSync(dockerfilePath)) {
80
+ info.hasDocker = true;
81
+ const content = fs.readFileSync(dockerfilePath, "utf-8");
82
+ const portMatch = content.match(/EXPOSE\s+(\d+)/);
83
+ if (portMatch)
84
+ info.dockerPort = portMatch[1];
85
+ }
86
+ return info;
87
+ }
88
+ //# sourceMappingURL=detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ import * as p from "@clack/prompts";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import { detectProject } from "./detector.js";
6
+ import { promptAuthor, promptContributors, promptDescription, promptDocker, promptEnvVars, promptLicense, promptLocalInstall, promptTests, promptUsage, promptWithCancel, } from "./prompts.js";
7
+ import { buildTableOfContents, detectMissingFields, fillTemplate, loadTemplate, } from "./template.js";
8
+ async function main() {
9
+ p.intro("📝 README Generator");
10
+ const projectPath = process.argv[2] ?? process.cwd();
11
+ p.log.info(`Reading project at: ${projectPath}`);
12
+ const info = detectProject(projectPath);
13
+ const allDeps = { ...info.dependencies, ...info.devDependencies };
14
+ const techList = Object.keys(allDeps)
15
+ .map((dep) => `* [${dep}](https://npmjs.com/package/${dep})`)
16
+ .join("\n");
17
+ const description = await promptDescription(info);
18
+ const { author, githubUser } = await promptAuthor(info);
19
+ const { hasDocker, dockerPort } = await promptDocker(info);
20
+ const envVars = await promptEnvVars(info);
21
+ const testCommand = await promptTests(info);
22
+ const runCommand = await promptLocalInstall(info);
23
+ const usageCommand = await promptUsage(info);
24
+ const contributorsTable = await promptContributors();
25
+ const license = await promptLicense(info);
26
+ const licenseBadge = license
27
+ ? `![License](https://img.shields.io/static/v1?label=License&message=${encodeURIComponent(license)}&color=0000ff&style=for-the-badge)`
28
+ : undefined;
29
+ const tableOfContents = buildTableOfContents({
30
+ env_vars: envVars,
31
+ has_docker: hasDocker,
32
+ contributors_table: contributorsTable,
33
+ license,
34
+ author,
35
+ usage_command: usageCommand,
36
+ test_command: testCommand,
37
+ run_command: runCommand,
38
+ });
39
+ const data = {
40
+ ...info,
41
+ project_name: info.name,
42
+ tech_list: techList,
43
+ description,
44
+ author,
45
+ github_user: githubUser,
46
+ env_vars: envVars,
47
+ has_docker: hasDocker,
48
+ docker_port: dockerPort,
49
+ contributors_table: contributorsTable,
50
+ license,
51
+ license_badge: licenseBadge,
52
+ usage_command: usageCommand,
53
+ test_command: testCommand,
54
+ run_command: runCommand,
55
+ table_of_contents: tableOfContents,
56
+ };
57
+ const templatePath = process.argv[3];
58
+ const template = loadTemplate(templatePath);
59
+ const missing = detectMissingFields(template, data);
60
+ const extras = {};
61
+ if (missing.length > 0) {
62
+ p.log.warn("Some fields were not detected automatically:");
63
+ for (const field of missing) {
64
+ const value = await promptWithCancel(p.text({
65
+ message: `What is the value of "${field}"?`,
66
+ placeholder: field,
67
+ }));
68
+ extras[field] = value;
69
+ }
70
+ }
71
+ const readme = fillTemplate(template, data, extras);
72
+ const outputPath = path.join(projectPath, "README.md");
73
+ fs.writeFileSync(outputPath, readme);
74
+ p.outro(`✅ README.md generated at ${outputPath}`);
75
+ }
76
+ main();
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { ProjectInfo } from "./detector.js";
2
+ export declare function promptWithCancel<T>(promise: Promise<T | symbol>): Promise<T>;
3
+ export declare function promptDescription(info: ProjectInfo): Promise<string>;
4
+ export declare function promptAuthor(info: ProjectInfo): Promise<{
5
+ author: string | undefined;
6
+ githubUser: string | undefined;
7
+ }>;
8
+ export declare function promptDocker(info: ProjectInfo): Promise<{
9
+ hasDocker: string | undefined;
10
+ dockerPort: string | undefined;
11
+ }>;
12
+ export declare function promptEnvVars(info: ProjectInfo): Promise<string | undefined>;
13
+ export declare function promptContributors(): Promise<string | undefined>;
14
+ export declare function promptLicense(info: ProjectInfo): Promise<string | undefined>;
15
+ export declare function promptTests(info: ProjectInfo): Promise<string | undefined>;
16
+ export declare function promptLocalInstall(info: ProjectInfo): Promise<string | undefined>;
17
+ export declare function promptUsage(info: ProjectInfo): Promise<string | undefined>;
18
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOlF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB1E;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC,CAiDzE;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC,CAwB5E;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAWlF;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiBtE;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqBlF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmChF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA2BvF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA6BhF"}
@@ -0,0 +1,175 @@
1
+ import * as p from "@clack/prompts";
2
+ import { buildContributorsTable } from "./template.js";
3
+ export async function promptWithCancel(promise) {
4
+ const result = await promise;
5
+ if (p.isCancel(result)) {
6
+ p.cancel("Operation cancelled.");
7
+ process.exit(0);
8
+ }
9
+ return result;
10
+ }
11
+ export async function promptDescription(info) {
12
+ if (info.description) {
13
+ const useDetected = await promptWithCancel(p.confirm({ message: `Detected description: "${info.description}". Use it?` }));
14
+ if (useDetected)
15
+ return info.description;
16
+ }
17
+ return promptWithCancel(p.text({
18
+ message: "Write the project description:",
19
+ placeholder: "An amazing project that does...",
20
+ validate: (v) => !v || v.trim() === "" ? "Description cannot be empty." : undefined,
21
+ }));
22
+ }
23
+ export async function promptAuthor(info) {
24
+ const showAuthor = await promptWithCancel(p.confirm({ message: "Display author in the README?" }));
25
+ if (!showAuthor)
26
+ return { author: undefined, githubUser: undefined };
27
+ let author = info.author;
28
+ let githubUser = info.githubUser;
29
+ if (author) {
30
+ const useDetected = await promptWithCancel(p.confirm({ message: `Detected author: "${author}". Use it?` }));
31
+ if (!useDetected) {
32
+ author = undefined;
33
+ githubUser = undefined;
34
+ }
35
+ }
36
+ if (!author) {
37
+ author = await promptWithCancel(p.text({
38
+ message: "What is your name?",
39
+ placeholder: "Beatriz Salles",
40
+ validate: (v) => !v || v.trim() === "" ? "Author cannot be empty." : undefined,
41
+ }));
42
+ }
43
+ if (githubUser) {
44
+ const useDetected = await promptWithCancel(p.confirm({ message: `Detected GitHub user: "${githubUser}". Use it?` }));
45
+ if (!useDetected)
46
+ githubUser = undefined;
47
+ }
48
+ if (!githubUser) {
49
+ githubUser = await promptWithCancel(p.text({
50
+ message: "What is your GitHub username?",
51
+ placeholder: "your-username",
52
+ validate: (v) => !v || v.trim() === "" ? "Username cannot be empty." : undefined,
53
+ }));
54
+ }
55
+ return { author, githubUser };
56
+ }
57
+ export async function promptDocker(info) {
58
+ if (!info.hasDocker)
59
+ return { hasDocker: undefined, dockerPort: undefined };
60
+ p.log.success(`Dockerfile detected! Port: ${info.dockerPort ?? "not found"}`);
61
+ const showDocker = await promptWithCancel(p.confirm({ message: "Display Docker section?" }));
62
+ if (!showDocker)
63
+ return { hasDocker: undefined, dockerPort: undefined };
64
+ if (info.dockerPort) {
65
+ return { hasDocker: "true", dockerPort: info.dockerPort };
66
+ }
67
+ const dockerPort = await promptWithCancel(p.text({
68
+ message: "What is the application port?",
69
+ placeholder: "3000",
70
+ validate: (v) => !v || v.trim() === "" ? "Port cannot be empty." : undefined,
71
+ }));
72
+ return { hasDocker: "true", dockerPort };
73
+ }
74
+ export async function promptEnvVars(info) {
75
+ if (!info.envVars || info.envVars.length === 0)
76
+ return undefined;
77
+ p.log.success(`Detected variables: ${info.envVars.join(", ")}`);
78
+ const showEnvVars = await promptWithCancel(p.confirm({ message: "Display environment variables section?" }));
79
+ if (!showEnvVars)
80
+ return undefined;
81
+ return info.envVars.join("\n");
82
+ }
83
+ export async function promptContributors() {
84
+ const showContributors = await promptWithCancel(p.confirm({ message: "Display contributors list?" }));
85
+ if (!showContributors)
86
+ return undefined;
87
+ const written = await promptWithCancel(p.text({
88
+ message: "List contributors in the format Name--username (for multiple, separate with commas):",
89
+ placeholder: "John Doe--jdoe, Mary Jane--mjay",
90
+ validate: (v) => !v || v.trim() === "" ? "Enter at least one contributor." : undefined,
91
+ }));
92
+ const normalized = written.split(",").map((v) => v.trim()).join("\n");
93
+ return buildContributorsTable(normalized);
94
+ }
95
+ export async function promptLicense(info) {
96
+ if (info.license) {
97
+ const useDetected = await promptWithCancel(p.confirm({ message: `Detected license: "${info.license}". Use it?` }));
98
+ if (useDetected)
99
+ return info.license;
100
+ }
101
+ const showLicense = await promptWithCancel(p.confirm({ message: "Display license section?" }));
102
+ if (!showLicense)
103
+ return undefined;
104
+ return promptWithCancel(p.text({
105
+ message: "What is the project license?",
106
+ placeholder: "MIT",
107
+ validate: (v) => !v || v.trim() === "" ? "License cannot be empty." : undefined,
108
+ }));
109
+ }
110
+ export async function promptTests(info) {
111
+ if (info.testCommand) {
112
+ const showTests = await promptWithCancel(p.confirm({ message: `Detected test command: "${info.testCommand}". Display tests section?` }));
113
+ if (!showTests)
114
+ return undefined;
115
+ const useCommand = await promptWithCancel(p.confirm({ message: `Use "${info.testCommand}" as test command?` }));
116
+ if (useCommand)
117
+ return info.testCommand;
118
+ return promptWithCancel(p.text({
119
+ message: "What is the command to run the tests?",
120
+ placeholder: "npm test",
121
+ validate: (v) => !v || v.trim() === "" ? "Command cannot be empty." : undefined,
122
+ }));
123
+ }
124
+ const showTests = await promptWithCancel(p.confirm({ message: "Display tests section?" }));
125
+ if (!showTests)
126
+ return undefined;
127
+ return promptWithCancel(p.text({
128
+ message: "What is the command to run the tests?",
129
+ placeholder: "npm test",
130
+ validate: (v) => !v || v.trim() === "" ? "Command cannot be empty." : undefined,
131
+ }));
132
+ }
133
+ export async function promptLocalInstall(info) {
134
+ const showLocal = await promptWithCancel(p.confirm({ message: "Display local installation section?" }));
135
+ if (!showLocal)
136
+ return undefined;
137
+ const priority = ["dev", "start", "serve", "preview"];
138
+ const detectedScripts = priority
139
+ .filter((s) => s in (info.scripts ?? {}))
140
+ .map((s) => `npm run ${s}`);
141
+ const firstScript = detectedScripts[0];
142
+ if (firstScript) {
143
+ const useDetected = await promptWithCancel(p.confirm({ message: `Use "${firstScript}" as run command?` }));
144
+ if (useDetected)
145
+ return firstScript;
146
+ }
147
+ return promptWithCancel(p.text({
148
+ message: "What is the command to run the project locally?",
149
+ placeholder: "npm run dev",
150
+ validate: (v) => !v || v.trim() === "" ? "Command cannot be empty." : undefined,
151
+ }));
152
+ }
153
+ export async function promptUsage(info) {
154
+ const showUsage = await promptWithCancel(p.confirm({ message: "Display usage section?" }));
155
+ if (!showUsage)
156
+ return undefined;
157
+ const priority = ["start", "dev", "serve", "preview"];
158
+ const detectedScripts = priority
159
+ .filter((s) => s in (info.scripts ?? {}))
160
+ .map((s) => `npm run ${s}`);
161
+ if (detectedScripts.length > 0) {
162
+ const firstScript = detectedScripts[0];
163
+ if (firstScript) {
164
+ const useDetected = await promptWithCancel(p.confirm({ message: `Use "${firstScript}" as usage command?` }));
165
+ if (useDetected)
166
+ return firstScript;
167
+ }
168
+ }
169
+ return promptWithCancel(p.text({
170
+ message: "What is the command to use the project?",
171
+ placeholder: "npx readme-gen or npm start",
172
+ validate: (v) => !v || v.trim() === "" ? "Command cannot be empty." : undefined,
173
+ }));
174
+ }
175
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ProjectInfo } from "./detector.js";
2
+ export interface TemplateData extends ProjectInfo {
3
+ tech_list?: string;
4
+ project_name?: string;
5
+ env_vars?: string;
6
+ has_docker?: string;
7
+ docker_port?: string;
8
+ github_user?: string;
9
+ contributors_table?: string;
10
+ license_badge?: string;
11
+ table_of_contents?: string;
12
+ usage_command?: string;
13
+ test_command?: string;
14
+ run_command?: string;
15
+ }
16
+ export declare function loadTemplate(templatePath?: string): string;
17
+ export declare function buildContributorsTable(input: string): string;
18
+ export declare function fillTemplate(template: string, data: TemplateData, extras?: Record<string, string>): string;
19
+ export declare function detectMissingFields(template: string, data: TemplateData): string[];
20
+ export declare function buildTableOfContents(data: TemplateData): string;
21
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiC5D;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,MAAM,CAkBR;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,YAAY,GACjB,MAAM,EAAE,CAiBV;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAyB/D"}
@@ -0,0 +1,89 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ export function loadTemplate(templatePath) {
5
+ const defaultPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "../templates/default.md");
6
+ const filePath = templatePath ?? defaultPath;
7
+ return fs.readFileSync(filePath, "utf-8");
8
+ }
9
+ export function buildContributorsTable(input) {
10
+ const contributors = input
11
+ .split("\n")
12
+ .map((line) => line.trim())
13
+ .filter(Boolean)
14
+ .map((line) => {
15
+ const [name, user] = line.split("--");
16
+ return { name: name?.trim(), user: user?.trim() };
17
+ })
18
+ .filter((c) => c.name && c.user);
19
+ const rows = [];
20
+ const chunkSize = 3;
21
+ for (let i = 0; i < contributors.length; i += chunkSize) {
22
+ const chunk = contributors.slice(i, i + chunkSize);
23
+ const cells = chunk
24
+ .map((c) => `
25
+ <td align="center">
26
+ <a href="https://github.com/${c.user}">
27
+ <img src="https://avatars.githubusercontent.com/${c.user}" width="100px;" alt="${c.name}"/><br>
28
+ <sub><b>${c.name}</b></sub>
29
+ </a>
30
+ </td>`)
31
+ .join("");
32
+ rows.push(` <tr>${cells}\n </tr>`);
33
+ }
34
+ return `<table>\n${rows.join("\n")}\n</table>`;
35
+ }
36
+ export function fillTemplate(template, data, extras = {}) {
37
+ const allData = { ...data, ...extras };
38
+ let result = template;
39
+ for (const [key, value] of Object.entries(allData)) {
40
+ if (typeof value === "string") {
41
+ result = result.replaceAll(`{{${key}}}`, value);
42
+ }
43
+ }
44
+ result = result.replace(/\{\{#if (\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, key, block) => {
45
+ return allData[key] ? block : "";
46
+ });
47
+ return result;
48
+ }
49
+ export function detectMissingFields(template, data) {
50
+ const matches = template.matchAll(/\{\{(\w+)\}\}/g);
51
+ const missing = [];
52
+ for (const match of matches) {
53
+ const key = match[1];
54
+ if (key !== undefined &&
55
+ key !== "if" &&
56
+ !(key in data) &&
57
+ !missing.includes(key)) {
58
+ missing.push(key);
59
+ }
60
+ }
61
+ return missing;
62
+ }
63
+ export function buildTableOfContents(data) {
64
+ const lines = [];
65
+ lines.push("* [About the Project](#book-about-the-project)");
66
+ if (data.usage_command)
67
+ lines.push(" * [Usage](#coffee-usage)");
68
+ lines.push(" * [Technologies](#computer-technologies)");
69
+ lines.push("* [Installation](#bricks-installation)");
70
+ lines.push(" * [Prerequisites](#construction-prerequisites)");
71
+ lines.push(" * [Installing Dependencies](#construction-installing-dependencies)");
72
+ if (data.env_vars)
73
+ lines.push(" * [Environment Variables](#wrench-environment-variables)");
74
+ if (data.has_docker)
75
+ lines.push(" * [Running with Docker](#whale-running-with-docker)");
76
+ if (data.run_command)
77
+ lines.push(" * [Running](#arrow_forward-running)");
78
+ if (data.test_command)
79
+ lines.push(" * [Running Tests](#test_tube-running-tests)");
80
+ lines.push("* [Contributing](#handshake-contributing)");
81
+ if (data.contributors_table)
82
+ lines.push("* [Contributors](#contributors)");
83
+ if (data.license)
84
+ lines.push("* [License](#page_facing_up-license)");
85
+ if (data.author)
86
+ lines.push("* [Author](#technologist-author)");
87
+ return lines.join("\n");
88
+ }
89
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "readme-cli-gen",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "description": "CLI tool that automatically generates README.md files by reading your project's files and asking only for the missing information.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {