Skip to content

Commit 5e98588

Browse files
Complete TypeScript migration: Add strict types, build system, and GitHub Pages deployment
- Migrated all code to TypeScript with strict type checking - Reorganized structure: src/core/ and src/web/ - Added comprehensive type definitions in src/core/types.ts - Updated build system to output dist/script.js - Fixed CLI tool (removed duplicate shebang) - Updated GitHub Actions workflow for Pages deployment - All tests passing: typecheck, build, CLI working - Web app ready for deployment
1 parent 9342774 commit 5e98588

31 files changed

+425
-191
lines changed

.github/workflows/pages.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Build and Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: "pages"
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: 20
28+
cache: npm
29+
30+
- name: Install
31+
run: npm ci
32+
33+
- name: Typecheck
34+
run: npm run typecheck
35+
36+
- name: Build
37+
run: npm run build
38+
39+
- name: Configure Pages
40+
uses: actions/configure-pages@v5
41+
42+
- name: Upload artifact
43+
uses: actions/upload-pages-artifact@v3
44+
with:
45+
path: dist
46+
47+
deploy:
48+
runs-on: ubuntu-latest
49+
needs: build
50+
environment:
51+
name: github-pages
52+
steps:
53+
- name: Deploy
54+
uses: actions/deploy-pages@v4

TESTING.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Testing Guide
2+
3+
## Quick Test Commands
4+
5+
### 1. Type Check
6+
```bash
7+
npm run typecheck
8+
```
9+
Should show: **0 errors**
10+
11+
### 2. Build
12+
```bash
13+
npm run build
14+
```
15+
Should create `dist/` folder with:
16+
- `dist/index.html`
17+
- `dist/script.js`
18+
- `dist/style.css`
19+
- `dist/data/` (word lists)
20+
- `dist/cli/index.js`
21+
22+
### 3. Test CLI Tool
23+
24+
#### Basic password:
25+
```bash
26+
./dist/cli/index.js pwd --len 16
27+
```
28+
29+
#### Passphrase:
30+
```bash
31+
./dist/cli/index.js passphrase --words 6
32+
```
33+
34+
#### User IDs:
35+
```bash
36+
./dist/cli/index.js userid --mode cvc --count 5
37+
```
38+
39+
#### JSON output:
40+
```bash
41+
./dist/cli/index.js pwd --len 20 --json
42+
```
43+
44+
#### iCloud passwords:
45+
```bash
46+
./dist/cli/index.js icloud --count 3
47+
```
48+
49+
### 4. Test Web App Locally
50+
51+
#### Option A: Using serve (recommended)
52+
```bash
53+
npm run serve:dist
54+
```
55+
Then open: `http://localhost:3000` (or the URL shown)
56+
57+
#### Option B: Using the custom server
58+
```bash
59+
npm start
60+
```
61+
Then open: `http://localhost:8000`
62+
63+
## What to Test in the Web App
64+
65+
### Password Tab:
66+
- [ ] Generate strong password (default mode)
67+
- [ ] Change length and regenerate
68+
- [ ] Toggle character types (lowercase, uppercase, digits, symbols)
69+
- [ ] Custom symbols input
70+
- [ ] iCloud mode generates password
71+
- [ ] Easy to write mode
72+
- [ ] Easy to say mode
73+
- [ ] Passphrase (Diceware) mode
74+
- [ ] Entropy and crack time display updates
75+
- [ ] Change hardware profile and see crack time update
76+
- [ ] Copy button works
77+
- [ ] Share button generates URL
78+
- [ ] Clear button resets everything
79+
80+
### User ID Tab:
81+
- [ ] Switch to User ID tab
82+
- [ ] Generate CVC user IDs
83+
- [ ] Generate Words user IDs
84+
- [ ] Change settings (syllables, words count, separator)
85+
- [ ] Copy individual user IDs
86+
- [ ] Share button generates URL
87+
- [ ] Reset settings button works
88+
89+
### Share Links:
90+
- [ ] Copy share link from Password tab
91+
- [ ] Open in new tab/window
92+
- [ ] Settings restore correctly
93+
- [ ] Password auto-generates (if `auto=1` in URL)
94+
- [ ] Copy share link from User ID tab
95+
- [ ] Settings restore correctly
96+
- [ ] User IDs auto-generate (if `auto=1` in URL)
97+
98+
### Persistence:
99+
- [ ] Change settings
100+
- [ ] Refresh page
101+
- [ ] Settings are restored
102+
- [ ] Active tab is restored
103+
104+
## Expected Results
105+
106+
**Type check**: 0 errors
107+
**Build**: Creates complete `dist/` folder
108+
**CLI**: All commands work and produce output
109+
**Web app**: Loads, generates passwords/IDs, shows entropy, copy/share work
110+
**Share links**: Restore settings and auto-generate
111+
**Persistence**: Settings saved and restored on reload
112+
113+
## Troubleshooting
114+
115+
### CLI not working?
116+
- Make sure you ran `npm install` and `npm run build`
117+
- Check file is executable: `ls -l dist/cli/index.js`
118+
- Try: `node dist/cli/index.js pwd --len 16`
119+
120+
### Web app not loading?
121+
- Make sure you built: `npm run build`
122+
- Check `dist/` folder exists with files
123+
- Use a local server (not `file://`)
124+
- Check browser console for errors
125+
126+
### Type errors?
127+
- Run `npm run typecheck` to see all errors
128+
- Make sure all TypeScript files are in `src/`

build.mjs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ async function buildWeb() {
1919
console.log("Building web app...");
2020

2121
await build({
22-
entryPoints: ["js/init.ts"],
22+
entryPoints: ["src/web/main.ts"],
2323
bundle: true,
24-
outdir: "dist",
24+
outfile: "dist/script.js",
2525
format: "esm",
26-
target: "es2022",
26+
target: "es2020",
2727
platform: "browser",
2828
sourcemap: !isProduction,
2929
minify: isProduction,
@@ -32,15 +32,25 @@ async function buildWeb() {
3232
}
3333
});
3434

35-
// Copy and update HTML - change script reference to bundled JS
35+
// Copy and update HTML - change script reference to script.js and CSS to style.css
3636
if (!existsSync("dist")) mkdirSync("dist", { recursive: true });
37-
const htmlContent = readFileSync("index.html", "utf8");
38-
const updatedHtml = htmlContent.replace(
39-
/<script type="module" src="\.\/js\/init\.js"><\/script>/,
40-
'<script type="module" src="./init.js"></script>'
37+
let htmlContent = readFileSync("index.html", "utf8");
38+
htmlContent = htmlContent.replace(
39+
/<script type="module" src="[^"]*"><\/script>/,
40+
'<script type="module" src="./script.js"></script>'
41+
);
42+
htmlContent = htmlContent.replace(
43+
/href="\.\/styles\.css"/,
44+
'href="./style.css"'
4145
);
42-
writeFileSync("dist/index.html", updatedHtml);
43-
copyFileSync("styles.css", "dist/styles.css");
46+
writeFileSync("dist/index.html", htmlContent);
47+
48+
// Copy style.css (note: keeping styles.css name for now, but copying as style.css per requirements)
49+
if (existsSync("styles.css")) {
50+
copyFileSync("styles.css", "dist/style.css");
51+
} else if (existsSync("style.css")) {
52+
copyFileSync("style.css", "dist/style.css");
53+
}
4454

4555
// Copy data files
4656
if (!existsSync("dist/data")) mkdirSync("dist/data", { recursive: true });
@@ -62,7 +72,7 @@ async function buildCLI() {
6272
await build({
6373
entryPoints: ["cli/index.ts"],
6474
bundle: true,
65-
outdir: "dist/cli",
75+
outfile: "dist/cli/index.js",
6676
format: "esm",
6777
target: "node18",
6878
platform: "node",
@@ -73,6 +83,10 @@ async function buildCLI() {
7383
}
7484
});
7585

86+
// Make CLI executable
87+
const { chmodSync } = await import("fs");
88+
chmodSync("dist/cli/index.js", 0o755);
89+
7690
console.log("CLI built successfully!");
7791
}
7892

@@ -82,9 +96,9 @@ async function buildCore() {
8296
// Core is used by both web and CLI, so we build it separately
8397
// Web will bundle it, CLI will use it directly
8498
await build({
85-
entryPoints: ["core/index.ts"],
99+
entryPoints: ["src/core/index.ts"],
86100
bundle: false,
87-
outdir: "dist/core",
101+
outdir: "dist/src/core",
88102
format: "esm",
89103
target: "es2022",
90104
platform: "neutral",
@@ -117,9 +131,10 @@ async function main() {
117131
console.log("\n✅ Build complete!");
118132
console.log("📦 Output: dist/");
119133
console.log(" - dist/index.html (web app)");
120-
console.log(" - dist/init.js (bundled web JS)");
134+
console.log(" - dist/script.js (bundled web JS)");
135+
console.log(" - dist/style.css");
136+
console.log(" - dist/data/ (word lists)");
121137
console.log(" - dist/cli/index.js (CLI executable)");
122-
console.log(" - dist/core/ (core library)");
123138

124139
} catch (error) {
125140
console.error("Build failed:", error);

cli/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#!/usr/bin/env node
2-
31
import fs from "node:fs";
42
import { parseArgs, type ParsedArgs } from "./parseArgs.js";
53
import { formatText, formatJSON } from "./output.js";
@@ -17,8 +15,8 @@ import {
1715
calculateEntropyBits,
1816
estimateCrackTimeSeconds,
1917
CRACK_HARDWARE_PROFILES
20-
} from "../core/index.js";
21-
import type { PasswordResult } from "../core/types.js";
18+
} from "../src/core/index.js";
19+
import type { PasswordResult } from "../src/core/types.js";
2220

2321
// Load word lists
2422
const dicewareWords: string[] = JSON.parse(

cli/output.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { formatCrackTime, CRACK_HARDWARE_PROFILES } from "../core/index.js";
2-
import type { PasswordResult } from "../core/types.js";
1+
import { formatCrackTime, CRACK_HARDWARE_PROFILES } from "../src/core/index.js";
2+
import type { PasswordResult } from "../src/core/types.js";
33

44
interface ResultWithValue {
55
value: string;

cli/random.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// cli/random.ts
22
import { randomInt as nodeRandomInt } from "node:crypto";
3-
import type { RandomIntFunction } from "../core/types.js";
3+
import type { RandomIntFunction } from "../src/core/types.js";
44

55
export function randomInt(max: number): number {
66
return nodeRandomInt(max);

core/types.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,6 @@ <h2>User ID Generator</h2>
231231

232232
</div>
233233

234-
<script type="module" src="./js/init.js"></script>
234+
<script type="module" src="./script.js"></script>
235235
</body>
236236
</html>

0 commit comments

Comments
 (0)