hatchkit 0.1.26 → 0.1.28

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.
@@ -0,0 +1,78 @@
1
+ /*
2
+ * Tiny helpers for keeping `.env.keys` (and friends) out of git.
3
+ *
4
+ * Used by `hatchkit adopt` because the user's repo predates hatchkit
5
+ * and may not have `.env.keys` in `.gitignore`. The first time we
6
+ * generate `.env.keys`, we MUST also ensure it's gitignored — otherwise
7
+ * the next `git add -A` sweeps the dotenvx private key into the repo,
8
+ * and a `git push` to a public remote leaks it forever.
9
+ *
10
+ * The defensive guard lives here too: scan a candidate file's first
11
+ * few lines for the `DOTENV_PRIVATE_KEY` substring (matches both the
12
+ * literal `DOTENV_PRIVATE_KEY_PRODUCTION=…` line and the `.env.keys`
13
+ * banner comment that dotenvx emits). Used as belt-and-braces around
14
+ * `git add` to refuse to stage anything that smells like a private key,
15
+ * regardless of `.gitignore` state.
16
+ */
17
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
18
+ import { join } from "node:path";
19
+ /** Marker block we own inside `.gitignore`. The leading newline keeps
20
+ * the new section visually separate from whatever the user already
21
+ * had (or no-op'd if they had nothing — git tolerates leading blanks).
22
+ * The `# hatchkit:` comment is a bread crumb so a curious user can
23
+ * trace where the line came from. */
24
+ const SECTION_HEADER = "# hatchkit: dotenvx private keys (NEVER commit)";
25
+ /** Append `patterns` to `<repoRoot>/.gitignore` if not already present.
26
+ * Creates the file when missing. Considers a pattern "present" when an
27
+ * existing line matches it exactly after trimming whitespace + a
28
+ * leading `/` — handles both `.env.keys` and `/.env.keys` / repo-root
29
+ * patterns the user may already have. */
30
+ export function ensureGitignoreEntries(repoRoot, patterns) {
31
+ const path = join(repoRoot, ".gitignore");
32
+ const fileCreated = !existsSync(path);
33
+ const existing = fileCreated ? "" : readFileSync(path, "utf-8");
34
+ const existingLines = new Set(existing
35
+ .split(/\r?\n/)
36
+ .map((l) => l.trim().replace(/^\/+/, ""))
37
+ .filter((l) => l.length > 0 && !l.startsWith("#")));
38
+ const added = [];
39
+ const alreadyPresent = [];
40
+ for (const p of patterns) {
41
+ const norm = p.trim().replace(/^\/+/, "");
42
+ if (existingLines.has(norm)) {
43
+ alreadyPresent.push(p);
44
+ }
45
+ else {
46
+ added.push(p);
47
+ }
48
+ }
49
+ if (added.length === 0) {
50
+ return { fileCreated: false, added, alreadyPresent, path };
51
+ }
52
+ // Build the appended block. End the file with a trailing newline so
53
+ // a subsequent append doesn't glue onto the same physical line.
54
+ const needsLeadingNewline = existing.length > 0 && !existing.endsWith("\n");
55
+ const block = `${needsLeadingNewline ? "\n" : ""}${existing.length > 0 ? "\n" : ""}${SECTION_HEADER}\n${added.join("\n")}\n`;
56
+ writeFileSync(path, existing + block);
57
+ return { fileCreated, added, alreadyPresent, path };
58
+ }
59
+ /** True iff the file's first `lines` lines contain the literal string
60
+ * `DOTENV_PRIVATE_KEY`. Disjoint from `DOTENV_PUBLIC_KEY` (they share
61
+ * no common substring beyond `DOTENV_`), so this is safe against the
62
+ * encrypted-but-public-key header dotenvx writes into `.env.production`. */
63
+ export function looksLikeDotenvxPrivateKey(filePath, lines = 10) {
64
+ if (!existsSync(filePath))
65
+ return false;
66
+ let head;
67
+ try {
68
+ head = readFileSync(filePath, "utf-8");
69
+ }
70
+ catch {
71
+ // Binary / unreadable / permission denied — bail safely (treat as
72
+ // "not a private key" so we don't block staging legit binaries).
73
+ return false;
74
+ }
75
+ const slice = head.split(/\r?\n/, lines).join("\n");
76
+ return slice.includes("DOTENV_PRIVATE_KEY");
77
+ }
78
+ //# sourceMappingURL=gitignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/utils/gitignore.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hatchkit",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "packageManager": "pnpm@10.33.2",
5
5
  "description": "Interactive CLI for scaffolding full-stack projects and provisioning observability/email clients",
6
6
  "type": "module",