trustlocal 0.1.0
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/LICENSE +21 -0
- package/README.md +129 -0
- package/dist/commands/init.d.ts +25 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +289 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/renew.d.ts +16 -0
- package/dist/commands/renew.d.ts.map +1 -0
- package/dist/commands/renew.js +54 -0
- package/dist/commands/renew.js.map +1 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +140 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +13 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +111 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/config/trustlocal.d.ts +40 -0
- package/dist/config/trustlocal.d.ts.map +1 -0
- package/dist/config/trustlocal.js +54 -0
- package/dist/config/trustlocal.js.map +1 -0
- package/dist/detector/framework.d.ts +14 -0
- package/dist/detector/framework.d.ts.map +1 -0
- package/dist/detector/framework.js +89 -0
- package/dist/detector/framework.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/injectors/astHelper.d.ts +35 -0
- package/dist/injectors/astHelper.d.ts.map +1 -0
- package/dist/injectors/astHelper.js +192 -0
- package/dist/injectors/astHelper.js.map +1 -0
- package/dist/injectors/express.d.ts +22 -0
- package/dist/injectors/express.d.ts.map +1 -0
- package/dist/injectors/express.js +59 -0
- package/dist/injectors/express.js.map +1 -0
- package/dist/injectors/nextjs.d.ts +24 -0
- package/dist/injectors/nextjs.d.ts.map +1 -0
- package/dist/injectors/nextjs.js +116 -0
- package/dist/injectors/nextjs.js.map +1 -0
- package/dist/injectors/nginx.d.ts +23 -0
- package/dist/injectors/nginx.d.ts.map +1 -0
- package/dist/injectors/nginx.js +61 -0
- package/dist/injectors/nginx.js.map +1 -0
- package/dist/injectors/plain.d.ts +12 -0
- package/dist/injectors/plain.d.ts.map +1 -0
- package/dist/injectors/plain.js +36 -0
- package/dist/injectors/plain.js.map +1 -0
- package/dist/injectors/vite.d.ts +24 -0
- package/dist/injectors/vite.d.ts.map +1 -0
- package/dist/injectors/vite.js +125 -0
- package/dist/injectors/vite.js.map +1 -0
- package/dist/mkcert/check.d.ts +13 -0
- package/dist/mkcert/check.d.ts.map +1 -0
- package/dist/mkcert/check.js +38 -0
- package/dist/mkcert/check.js.map +1 -0
- package/dist/mkcert/generate.d.ts +26 -0
- package/dist/mkcert/generate.d.ts.map +1 -0
- package/dist/mkcert/generate.js +111 -0
- package/dist/mkcert/generate.js.map +1 -0
- package/dist/mkcert/install.d.ts +7 -0
- package/dist/mkcert/install.d.ts.map +1 -0
- package/dist/mkcert/install.js +75 -0
- package/dist/mkcert/install.js.map +1 -0
- package/dist/utils/backup.d.ts +7 -0
- package/dist/utils/backup.d.ts.map +1 -0
- package/dist/utils/backup.js +16 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +38 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/os.d.ts +4 -0
- package/dist/utils/os.d.ts.map +1 -0
- package/dist/utils/os.js +24 -0
- package/dist/utils/os.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sahil Kashyap
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# trustlocal
|
|
2
|
+
|
|
3
|
+
> One command. HTTPS everywhere. Zero config.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/trustlocal)
|
|
6
|
+
[](https://www.npmjs.com/package/trustlocal)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
`trustlocal` automates local HTTPS setup for web development projects. It uses [mkcert](https://github.com/FiloSottile/mkcert) to generate locally trusted certificates, then detects your framework and injects the correct SSL configuration — eliminating every manual step between *"I want HTTPS locally"* and *"it works."*
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx trustlocal init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
That's it. `trustlocal` will:
|
|
20
|
+
|
|
21
|
+
1. Install mkcert if not already present
|
|
22
|
+
2. Register the local CA (prompts for sudo once)
|
|
23
|
+
3. Detect your framework (Next.js, Vite, Express, Nginx, or plain)
|
|
24
|
+
4. Generate trusted certificates for `localhost` and `127.0.0.1`
|
|
25
|
+
5. Inject HTTPS config into your framework's config file
|
|
26
|
+
6. Set `NODE_EXTRA_CA_CERTS` in `.env`
|
|
27
|
+
7. Add `.trustlocal/` to `.gitignore`
|
|
28
|
+
8. Write `trustlocal.json` so teammates can sync with one command
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
### `init` — First-time setup
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx trustlocal init [--domains myapp.local] [--force] [--dry-run]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Flag | Description |
|
|
41
|
+
|------|-------------|
|
|
42
|
+
| `--domains <list>` | Comma-separated extra domains (e.g. `--domains myapp.local,api.local`) |
|
|
43
|
+
| `--force` | Re-initialise even if `trustlocal.json` already exists |
|
|
44
|
+
| `--dry-run` | Preview what would happen without writing any files |
|
|
45
|
+
|
|
46
|
+
### `sync` — Onboard a new teammate
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx trustlocal sync
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Reads `trustlocal.json`, generates fresh certs on the new machine (no private key sharing), injects config identically, and gets HTTPS working in under 30 seconds.
|
|
53
|
+
|
|
54
|
+
### `renew` — Renew expiring certs
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx trustlocal renew [--force]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Certs expire after 2 years. Deletes old certs and generates fresh ones. Framework config files are **not** touched — cert paths stay the same.
|
|
61
|
+
|
|
62
|
+
### `status` — Check your setup
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx trustlocal status
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Shows framework, cert expiry, config injection status, `NODE_EXTRA_CA_CERTS`, and `.gitignore` — with coloured OK / WARNING / ERROR indicators.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Supported frameworks
|
|
73
|
+
|
|
74
|
+
| Framework | Detection | Config target |
|
|
75
|
+
|-----------|-----------|---------------|
|
|
76
|
+
| **Next.js** | `next` in `package.json` | `next.config.js/ts` — `experimental.https` |
|
|
77
|
+
| **Vite** | `vite` in `package.json` | `vite.config.js/ts` — `server.https` |
|
|
78
|
+
| **Express / Node** | `express` in deps or `server.js` found | `.env` — `NODE_EXTRA_CA_CERTS` + printed snippet |
|
|
79
|
+
| **Nginx** | `nginx.conf` in project root | `nginx.conf` — `ssl_certificate` block |
|
|
80
|
+
| **Plain** | fallback | Certs placed in `.trustlocal/` with instructions |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## How it works
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
npx trustlocal init
|
|
88
|
+
|
|
89
|
+
→ Checking mkcert...
|
|
90
|
+
✓ mkcert 1.4.4 found
|
|
91
|
+
→ Detecting framework...
|
|
92
|
+
✓ Detected: Next.js (next.config.ts)
|
|
93
|
+
→ Generating certificates for: localhost, 127.0.0.1
|
|
94
|
+
✓ Certificates generated → .trustlocal/
|
|
95
|
+
→ Injecting HTTPS config into next.config.ts...
|
|
96
|
+
✓ Config updated
|
|
97
|
+
→ Updating .env...
|
|
98
|
+
✓ NODE_EXTRA_CA_CERTS set
|
|
99
|
+
→ Updating .gitignore...
|
|
100
|
+
✓ .trustlocal/ added to .gitignore
|
|
101
|
+
|
|
102
|
+
✓ Done! Open https://localhost:3000
|
|
103
|
+
|
|
104
|
+
Teammates: run npx trustlocal sync to get HTTPS on their machines.
|
|
105
|
+
Cert expires: 2028-03-31
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Security
|
|
111
|
+
|
|
112
|
+
- `.trustlocal/` (containing `.pem` files) is automatically added to `.gitignore` — **private keys are never committed**
|
|
113
|
+
- `trustlocal.json` is safe to commit — it contains no keys, only config metadata
|
|
114
|
+
- All cert generation happens locally via `mkcert`. `trustlocal` never reads, stores, or transmits any private key
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Requirements
|
|
119
|
+
|
|
120
|
+
- Node.js 18+
|
|
121
|
+
- macOS or Linux (Windows support is post-v1)
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT © Sahil Kashyap
|
|
128
|
+
|
|
129
|
+
Built with [Claude Code](https://claude.ai/claude-code)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx trustlocal init`
|
|
3
|
+
*
|
|
4
|
+
* Full execution flow (per spec §5.1):
|
|
5
|
+
* 1. Check Node version >= 18
|
|
6
|
+
* 2. Check if trustlocal.json already exists (require --force to continue)
|
|
7
|
+
* 3. Check / install mkcert
|
|
8
|
+
* 4. Run mkcert -install
|
|
9
|
+
* 5. Detect framework
|
|
10
|
+
* 6. Prompt user to confirm / override
|
|
11
|
+
* 7. Collect domains
|
|
12
|
+
* 8. Create .trustlocal/ and generate certs
|
|
13
|
+
* 9. Backup + inject HTTPS config
|
|
14
|
+
* 10. Add NODE_EXTRA_CA_CERTS to .env
|
|
15
|
+
* 11. Add .trustlocal/ to .gitignore
|
|
16
|
+
* 12. Write trustlocal.json
|
|
17
|
+
* 13. Print success summary
|
|
18
|
+
*/
|
|
19
|
+
export interface InitOptions {
|
|
20
|
+
domains?: string[];
|
|
21
|
+
force?: boolean;
|
|
22
|
+
dryRun?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function runInit(options?: InitOptions): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAmBH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+GD,wBAAsB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoItE"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `npx trustlocal init`
|
|
4
|
+
*
|
|
5
|
+
* Full execution flow (per spec §5.1):
|
|
6
|
+
* 1. Check Node version >= 18
|
|
7
|
+
* 2. Check if trustlocal.json already exists (require --force to continue)
|
|
8
|
+
* 3. Check / install mkcert
|
|
9
|
+
* 4. Run mkcert -install
|
|
10
|
+
* 5. Detect framework
|
|
11
|
+
* 6. Prompt user to confirm / override
|
|
12
|
+
* 7. Collect domains
|
|
13
|
+
* 8. Create .trustlocal/ and generate certs
|
|
14
|
+
* 9. Backup + inject HTTPS config
|
|
15
|
+
* 10. Add NODE_EXTRA_CA_CERTS to .env
|
|
16
|
+
* 11. Add .trustlocal/ to .gitignore
|
|
17
|
+
* 12. Write trustlocal.json
|
|
18
|
+
* 13. Print success summary
|
|
19
|
+
*/
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
+
var ownKeys = function(o) {
|
|
38
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
+
var ar = [];
|
|
40
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
+
return ar;
|
|
42
|
+
};
|
|
43
|
+
return ownKeys(o);
|
|
44
|
+
};
|
|
45
|
+
return function (mod) {
|
|
46
|
+
if (mod && mod.__esModule) return mod;
|
|
47
|
+
var result = {};
|
|
48
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
+
__setModuleDefault(result, mod);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
})();
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.runInit = runInit;
|
|
55
|
+
const promises_1 = require("fs/promises");
|
|
56
|
+
const path_1 = require("path");
|
|
57
|
+
const readline = __importStar(require("readline"));
|
|
58
|
+
const logger_1 = require("../utils/logger");
|
|
59
|
+
const framework_1 = require("../detector/framework");
|
|
60
|
+
const check_1 = require("../mkcert/check");
|
|
61
|
+
const install_1 = require("../mkcert/install");
|
|
62
|
+
const generate_1 = require("../mkcert/generate");
|
|
63
|
+
const trustlocal_1 = require("../config/trustlocal");
|
|
64
|
+
const nextjs_1 = require("../injectors/nextjs");
|
|
65
|
+
const vite_1 = require("../injectors/vite");
|
|
66
|
+
const express_1 = require("../injectors/express");
|
|
67
|
+
const nginx_1 = require("../injectors/nginx");
|
|
68
|
+
const plain_1 = require("../injectors/plain");
|
|
69
|
+
const check_2 = require("../mkcert/check");
|
|
70
|
+
/** Prompt the user with a question and return their answer. */
|
|
71
|
+
async function prompt(question) {
|
|
72
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
rl.question(` ${question} `, (answer) => {
|
|
75
|
+
rl.close();
|
|
76
|
+
resolve(answer.trim());
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/** Collect extra .local domains from .env file */
|
|
81
|
+
async function collectEnvDomains(cwd) {
|
|
82
|
+
try {
|
|
83
|
+
const content = await (0, promises_1.readFile)((0, path_1.join)(cwd, '.env'), 'utf-8');
|
|
84
|
+
const matches = content.matchAll(/(?:HOST|DOMAIN|URL)[^=]*=\s*([a-zA-Z0-9.-]+\.local)/g);
|
|
85
|
+
return [...matches].map((m) => m[1]);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Add a path to .gitignore if not already present. */
|
|
92
|
+
async function ensureGitignore(cwd, entry) {
|
|
93
|
+
const gitignorePath = (0, path_1.join)(cwd, '.gitignore');
|
|
94
|
+
let content = '';
|
|
95
|
+
try {
|
|
96
|
+
content = await (0, promises_1.readFile)(gitignorePath, 'utf-8');
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// File doesn't exist — create it
|
|
100
|
+
}
|
|
101
|
+
if (content.includes(entry))
|
|
102
|
+
return;
|
|
103
|
+
const newContent = content
|
|
104
|
+
? `${content.trimEnd()}\n\n# trustlocal — local TLS certs (never commit private keys)\n${entry}/\n`
|
|
105
|
+
: `# trustlocal — local TLS certs (never commit private keys)\n${entry}/\n`;
|
|
106
|
+
await (0, promises_1.writeFile)(gitignorePath, newContent, 'utf-8');
|
|
107
|
+
}
|
|
108
|
+
/** Add NODE_EXTRA_CA_CERTS to .env */
|
|
109
|
+
async function ensureNodeExtraCA(cwd, caRootPem) {
|
|
110
|
+
const envPath = (0, path_1.join)(cwd, '.env');
|
|
111
|
+
let content = '';
|
|
112
|
+
try {
|
|
113
|
+
content = await (0, promises_1.readFile)(envPath, 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// File doesn't exist
|
|
117
|
+
}
|
|
118
|
+
if (content.includes('NODE_EXTRA_CA_CERTS'))
|
|
119
|
+
return;
|
|
120
|
+
const line = `\n# trustlocal — allow Node.js to trust the local CA\nNODE_EXTRA_CA_CERTS=${caRootPem}\n`;
|
|
121
|
+
await (0, promises_1.writeFile)(envPath, content + line, 'utf-8');
|
|
122
|
+
}
|
|
123
|
+
/** Run the appropriate injector for the detected framework. */
|
|
124
|
+
async function runInjector(framework, configFile, cwd, caRootPem) {
|
|
125
|
+
switch (framework) {
|
|
126
|
+
case 'nextjs': {
|
|
127
|
+
const configPath = (0, path_1.join)(cwd, configFile ?? 'next.config.js');
|
|
128
|
+
const result = await (0, nextjs_1.injectNextjs)(configPath);
|
|
129
|
+
if (result.alreadyConfigured) {
|
|
130
|
+
logger_1.logger.warn('HTTPS already configured in Next.js config — skipping injection.');
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
logger_1.logger.success(`Config updated${result.created ? ' (new file created)' : ''}`);
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case 'vite': {
|
|
138
|
+
const configPath = (0, path_1.join)(cwd, configFile ?? 'vite.config.ts');
|
|
139
|
+
const result = await (0, vite_1.injectVite)(configPath);
|
|
140
|
+
if (result.alreadyConfigured) {
|
|
141
|
+
logger_1.logger.warn('HTTPS already configured in Vite config — skipping injection.');
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
logger_1.logger.success(`Config updated${result.created ? ' (new file created)' : ''}`);
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case 'express': {
|
|
149
|
+
const envPath = (0, path_1.join)(cwd, '.env');
|
|
150
|
+
await (0, express_1.injectExpress)(envPath, caRootPem);
|
|
151
|
+
logger_1.logger.success('NODE_EXTRA_CA_CERTS set in .env');
|
|
152
|
+
(0, express_1.printExpressSnippet)(trustlocal_1.CERT_DIR);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 'nginx': {
|
|
156
|
+
const configPath = (0, path_1.join)(cwd, configFile ?? 'nginx.conf');
|
|
157
|
+
const result = await (0, nginx_1.injectNginx)(configPath);
|
|
158
|
+
if (result.alreadyConfigured) {
|
|
159
|
+
logger_1.logger.warn('HTTPS already configured in nginx.conf — skipping injection.');
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
logger_1.logger.success('nginx.conf updated');
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case 'plain': {
|
|
167
|
+
(0, plain_1.printPlainInstructions)(trustlocal_1.CERT_DIR);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function runInit(options = {}) {
|
|
173
|
+
const cwd = process.cwd();
|
|
174
|
+
logger_1.logger.title('trustlocal init');
|
|
175
|
+
// ── 1. Node version check ─────────────────────────────────────────────────
|
|
176
|
+
const [major] = process.versions.node.split('.').map(Number);
|
|
177
|
+
if ((major ?? 0) < 18) {
|
|
178
|
+
logger_1.logger.error(`Node.js 18+ is required. You are running ${process.versions.node}.`);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
// ── 2. Existing trustlocal.json ────────────────────────────────────────────
|
|
182
|
+
const existing = await (0, trustlocal_1.readConfig)(cwd);
|
|
183
|
+
if (existing && !options.force) {
|
|
184
|
+
logger_1.logger.warn('trustlocal.json already exists in this project.');
|
|
185
|
+
logger_1.logger.info('Run with --force to re-initialise, or use `npx trustlocal sync` instead.');
|
|
186
|
+
process.exit(0);
|
|
187
|
+
}
|
|
188
|
+
// ── 3. Check / install mkcert ──────────────────────────────────────────────
|
|
189
|
+
logger_1.logger.step('Checking mkcert...');
|
|
190
|
+
const mkcertInfo = (0, check_1.checkMkcert)();
|
|
191
|
+
if (!mkcertInfo.installed) {
|
|
192
|
+
logger_1.logger.warn('mkcert not found — attempting auto-install...');
|
|
193
|
+
(0, install_1.installMkcert)();
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
logger_1.logger.success(`mkcert ${mkcertInfo.version ?? ''} found`);
|
|
197
|
+
}
|
|
198
|
+
// ── 4. mkcert -install (register local CA) ────────────────────────────────
|
|
199
|
+
logger_1.logger.step('Installing local CA (may prompt for sudo)...');
|
|
200
|
+
if (!options.dryRun) {
|
|
201
|
+
(0, generate_1.installCA)();
|
|
202
|
+
}
|
|
203
|
+
logger_1.logger.success('Local CA registered');
|
|
204
|
+
// ── 5. Detect framework ────────────────────────────────────────────────────
|
|
205
|
+
logger_1.logger.step('Detecting framework...');
|
|
206
|
+
let detection = await (0, framework_1.detectFramework)(cwd);
|
|
207
|
+
logger_1.logger.success(`Detected: ${(0, framework_1.frameworkDisplayName)(detection.framework)}${detection.configFile ? ` (${detection.configFile})` : ''}`);
|
|
208
|
+
// ── 6. Confirm / override ─────────────────────────────────────────────────
|
|
209
|
+
if (!options.dryRun) {
|
|
210
|
+
const answer = await prompt(`Use ${(0, framework_1.frameworkDisplayName)(detection.framework)}? [Y/n/override]`);
|
|
211
|
+
if (answer.toLowerCase() === 'n') {
|
|
212
|
+
logger_1.logger.info('Aborting. Run again to retry.');
|
|
213
|
+
process.exit(0);
|
|
214
|
+
}
|
|
215
|
+
const overrides = {
|
|
216
|
+
nextjs: 'nextjs', next: 'nextjs',
|
|
217
|
+
vite: 'vite',
|
|
218
|
+
express: 'express', node: 'express',
|
|
219
|
+
nginx: 'nginx',
|
|
220
|
+
plain: 'plain',
|
|
221
|
+
};
|
|
222
|
+
if (answer && answer.toLowerCase() !== 'y' && overrides[answer.toLowerCase()]) {
|
|
223
|
+
detection = { framework: overrides[answer.toLowerCase()] };
|
|
224
|
+
logger_1.logger.info(`Using ${(0, framework_1.frameworkDisplayName)(detection.framework)}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// ── 7. Collect domains ─────────────────────────────────────────────────────
|
|
228
|
+
const envDomains = await collectEnvDomains(cwd);
|
|
229
|
+
const extraDomains = options.domains ?? [];
|
|
230
|
+
const domains = ['localhost', '127.0.0.1', ...envDomains, ...extraDomains].filter((d, i, arr) => arr.indexOf(d) === i);
|
|
231
|
+
logger_1.logger.step(`Generating certificates for: ${domains.join(', ')}`);
|
|
232
|
+
// ── 8. Create .trustlocal/ and generate certs ─────────────────────────────
|
|
233
|
+
// .gitignore must be updated BEFORE writing cert files (per spec)
|
|
234
|
+
logger_1.logger.step('Updating .gitignore...');
|
|
235
|
+
if (!options.dryRun) {
|
|
236
|
+
await ensureGitignore(cwd, trustlocal_1.CERT_DIR);
|
|
237
|
+
}
|
|
238
|
+
logger_1.logger.success(`.trustlocal/ added to .gitignore`);
|
|
239
|
+
if (!options.dryRun) {
|
|
240
|
+
await (0, generate_1.generateCerts)(trustlocal_1.CERT_DIR, domains, cwd);
|
|
241
|
+
}
|
|
242
|
+
logger_1.logger.success(`Certificates generated → ${trustlocal_1.CERT_DIR}/`);
|
|
243
|
+
// ── 9. Inject HTTPS config ────────────────────────────────────────────────
|
|
244
|
+
logger_1.logger.step(`Injecting HTTPS config into ${detection.configFile ?? detection.framework}...`);
|
|
245
|
+
const caRootPem = mkcertInfo.caRoot
|
|
246
|
+
? `${mkcertInfo.caRoot}/rootCA.pem`
|
|
247
|
+
: `${(0, check_2.getMkcertCARoot)()}/rootCA.pem`;
|
|
248
|
+
if (!options.dryRun) {
|
|
249
|
+
await runInjector(detection.framework, detection.configFile, cwd, caRootPem);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
logger_1.logger.success('Config updated (dry-run)');
|
|
253
|
+
}
|
|
254
|
+
// ── 10. NODE_EXTRA_CA_CERTS in .env ──────────────────────────────────────
|
|
255
|
+
logger_1.logger.step('Updating .env...');
|
|
256
|
+
if (!options.dryRun) {
|
|
257
|
+
await ensureNodeExtraCA(cwd, caRootPem);
|
|
258
|
+
}
|
|
259
|
+
logger_1.logger.success('NODE_EXTRA_CA_CERTS set');
|
|
260
|
+
// ── 12. Write trustlocal.json ─────────────────────────────────────────────
|
|
261
|
+
const config = (0, trustlocal_1.buildConfig)({
|
|
262
|
+
framework: detection.framework,
|
|
263
|
+
domains,
|
|
264
|
+
certDir: trustlocal_1.CERT_DIR,
|
|
265
|
+
configFiles: detection.configFile ? [detection.configFile] : [],
|
|
266
|
+
});
|
|
267
|
+
if (!options.dryRun) {
|
|
268
|
+
await (0, trustlocal_1.writeConfig)(cwd, config);
|
|
269
|
+
}
|
|
270
|
+
// ── 13. Success summary ────────────────────────────────────────────────────
|
|
271
|
+
const certPath = (0, path_1.join)(cwd, trustlocal_1.CERT_DIR, generate_1.CERT_FILENAME);
|
|
272
|
+
const expiry = await (async () => {
|
|
273
|
+
if (options.dryRun)
|
|
274
|
+
return new Date(Date.now() + 2 * 365 * 24 * 3600 * 1000);
|
|
275
|
+
try {
|
|
276
|
+
return (0, generate_1.getCertExpiry)(certPath);
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return new Date(Date.now() + 2 * 365 * 24 * 3600 * 1000);
|
|
280
|
+
}
|
|
281
|
+
})();
|
|
282
|
+
logger_1.logger.blank();
|
|
283
|
+
logger_1.logger.success('Done! Open https://localhost:3000');
|
|
284
|
+
logger_1.logger.blank();
|
|
285
|
+
logger_1.logger.info('Teammates: run npx trustlocal sync to get HTTPS on their machines.');
|
|
286
|
+
logger_1.logger.info(`Cert expires: ${expiry.toISOString().split('T')[0]}`);
|
|
287
|
+
logger_1.logger.blank();
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx trustlocal renew`
|
|
3
|
+
*
|
|
4
|
+
* Execution flow (per spec §5.3):
|
|
5
|
+
* 1. Read trustlocal.json
|
|
6
|
+
* 2. Check cert expiry — warn if > 30 days remaining (require --force)
|
|
7
|
+
* 3. Delete old certs from .trustlocal/
|
|
8
|
+
* 4. Generate fresh certs
|
|
9
|
+
* 5. Print new expiry date
|
|
10
|
+
* (Config injection NOT repeated — cert file paths don't change)
|
|
11
|
+
*/
|
|
12
|
+
export interface RenewOptions {
|
|
13
|
+
force?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function runRenew(options?: RenewOptions): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=renew.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renew.d.ts","sourceRoot":"","sources":["../../src/commands/renew.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID,wBAAsB,QAAQ,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CxE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `npx trustlocal renew`
|
|
4
|
+
*
|
|
5
|
+
* Execution flow (per spec §5.3):
|
|
6
|
+
* 1. Read trustlocal.json
|
|
7
|
+
* 2. Check cert expiry — warn if > 30 days remaining (require --force)
|
|
8
|
+
* 3. Delete old certs from .trustlocal/
|
|
9
|
+
* 4. Generate fresh certs
|
|
10
|
+
* 5. Print new expiry date
|
|
11
|
+
* (Config injection NOT repeated — cert file paths don't change)
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.runRenew = runRenew;
|
|
15
|
+
const path_1 = require("path");
|
|
16
|
+
const logger_1 = require("../utils/logger");
|
|
17
|
+
const trustlocal_1 = require("../config/trustlocal");
|
|
18
|
+
const generate_1 = require("../mkcert/generate");
|
|
19
|
+
const DAYS_WARN_THRESHOLD = 30;
|
|
20
|
+
async function runRenew(options = {}) {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
logger_1.logger.title('trustlocal renew');
|
|
23
|
+
// ── 1. Read trustlocal.json ───────────────────────────────────────────────
|
|
24
|
+
const config = await (0, trustlocal_1.readConfig)(cwd);
|
|
25
|
+
if (!config) {
|
|
26
|
+
logger_1.logger.error('trustlocal.json not found.');
|
|
27
|
+
logger_1.logger.info('Run `npx trustlocal init` first.');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
// ── 2. Check cert expiry ──────────────────────────────────────────────────
|
|
31
|
+
const certPath = (0, path_1.join)(cwd, config.certDir, generate_1.CERT_FILENAME);
|
|
32
|
+
const expiry = (0, generate_1.getCertExpiry)(certPath);
|
|
33
|
+
const now = new Date();
|
|
34
|
+
const daysLeft = Math.floor((expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
|
35
|
+
logger_1.logger.info(`Current cert expires: ${expiry.toISOString().split('T')[0]} (${daysLeft} days remaining)`);
|
|
36
|
+
if (daysLeft > DAYS_WARN_THRESHOLD && !options.force) {
|
|
37
|
+
logger_1.logger.warn(`Cert is still valid for ${daysLeft} days.`);
|
|
38
|
+
logger_1.logger.info('Use --force to renew anyway.');
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
// ── 3. Delete old certs ───────────────────────────────────────────────────
|
|
42
|
+
logger_1.logger.step('Removing old certificates...');
|
|
43
|
+
await (0, generate_1.deleteCerts)(config.certDir, cwd);
|
|
44
|
+
logger_1.logger.success('Old certificates removed');
|
|
45
|
+
// ── 4. Generate fresh certs ────────────────────────────────────────────────
|
|
46
|
+
logger_1.logger.step(`Generating new certificates for: ${config.domains.join(', ')}`);
|
|
47
|
+
await (0, generate_1.generateCerts)(config.certDir, config.domains, cwd);
|
|
48
|
+
const newExpiry = (0, generate_1.getCertExpiry)(certPath);
|
|
49
|
+
logger_1.logger.success(`Certificates renewed → ${config.certDir}/`);
|
|
50
|
+
logger_1.logger.blank();
|
|
51
|
+
logger_1.logger.success(`New cert expires: ${newExpiry.toISOString().split('T')[0]}`);
|
|
52
|
+
logger_1.logger.blank();
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=renew.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renew.js","sourceRoot":"","sources":["../../src/commands/renew.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAcH,4BA0CC;AAtDD,+BAA4B;AAE5B,4CAAyC;AACzC,qDAAkD;AAClD,iDAA8F;AAM9F,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAExB,KAAK,UAAU,QAAQ,CAAC,UAAwB,EAAE;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,eAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAEjC,6EAA6E;IAC7E,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAU,EAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,eAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC3C,eAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,wBAAa,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAExF,eAAM,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,kBAAkB,CAAC,CAAC;IAExG,IAAI,QAAQ,GAAG,mBAAmB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrD,eAAM,CAAC,IAAI,CAAC,2BAA2B,QAAQ,QAAQ,CAAC,CAAC;QACzD,eAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,6EAA6E;IAC7E,eAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC5C,MAAM,IAAA,sBAAW,EAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACvC,eAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAE3C,8EAA8E;IAC9E,eAAM,CAAC,IAAI,CAAC,oCAAoC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,MAAM,IAAA,wBAAa,EAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAEzD,MAAM,SAAS,GAAG,IAAA,wBAAa,EAAC,QAAQ,CAAC,CAAC;IAC1C,eAAM,CAAC,OAAO,CAAC,0BAA0B,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAE5D,eAAM,CAAC,KAAK,EAAE,CAAC;IACf,eAAM,CAAC,OAAO,CAAC,qBAAqB,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,eAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx trustlocal status`
|
|
3
|
+
*
|
|
4
|
+
* Execution flow (per spec §5.4):
|
|
5
|
+
* 1. Read trustlocal.json — show error if missing
|
|
6
|
+
* 2. Print: framework, domains, cert location, expiry, days until expiry
|
|
7
|
+
* 3. Check if config injection is still present in framework config file
|
|
8
|
+
* 4. Check if NODE_EXTRA_CA_CERTS is set in .env
|
|
9
|
+
* 5. Check if .trustlocal/ is in .gitignore
|
|
10
|
+
* 6. Print coloured status line for each check
|
|
11
|
+
*/
|
|
12
|
+
export declare function runStatus(): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiDH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAgF/C"}
|