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
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `npx trustlocal status`
|
|
4
|
+
*
|
|
5
|
+
* Execution flow (per spec §5.4):
|
|
6
|
+
* 1. Read trustlocal.json — show error if missing
|
|
7
|
+
* 2. Print: framework, domains, cert location, expiry, days until expiry
|
|
8
|
+
* 3. Check if config injection is still present in framework config file
|
|
9
|
+
* 4. Check if NODE_EXTRA_CA_CERTS is set in .env
|
|
10
|
+
* 5. Check if .trustlocal/ is in .gitignore
|
|
11
|
+
* 6. Print coloured status line for each check
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.runStatus = runStatus;
|
|
18
|
+
const promises_1 = require("fs/promises");
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
21
|
+
const logger_1 = require("../utils/logger");
|
|
22
|
+
const trustlocal_1 = require("../config/trustlocal");
|
|
23
|
+
const generate_1 = require("../mkcert/generate");
|
|
24
|
+
const nextjs_1 = require("../injectors/nextjs");
|
|
25
|
+
const vite_1 = require("../injectors/vite");
|
|
26
|
+
const nginx_1 = require("../injectors/nginx");
|
|
27
|
+
const express_1 = require("../injectors/express");
|
|
28
|
+
const framework_1 = require("../detector/framework");
|
|
29
|
+
function statusLine(level, label, detail) {
|
|
30
|
+
const icon = level === 'OK' ? chalk_1.default.green('✓') : level === 'WARNING' ? chalk_1.default.yellow('⚠') : chalk_1.default.red('✗');
|
|
31
|
+
const color = level === 'OK' ? chalk_1.default.green : level === 'WARNING' ? chalk_1.default.yellow : chalk_1.default.red;
|
|
32
|
+
console.log(` ${icon} ${label.padEnd(30)} ${color(detail)}`);
|
|
33
|
+
}
|
|
34
|
+
async function fileExists(p) {
|
|
35
|
+
try {
|
|
36
|
+
await (0, promises_1.access)(p);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function fileContains(p, text) {
|
|
44
|
+
try {
|
|
45
|
+
const content = await (0, promises_1.readFile)(p, 'utf-8');
|
|
46
|
+
return content.includes(text);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Get the injection marker for the given framework config. */
|
|
53
|
+
function getInjectionMarker(framework) {
|
|
54
|
+
if (framework === 'nextjs')
|
|
55
|
+
return nextjs_1.INJECTION_MARKER;
|
|
56
|
+
if (framework === 'vite')
|
|
57
|
+
return vite_1.INJECTION_MARKER;
|
|
58
|
+
if (framework === 'nginx')
|
|
59
|
+
return nginx_1.INJECTION_MARKER;
|
|
60
|
+
return 'trustlocal:https';
|
|
61
|
+
}
|
|
62
|
+
async function runStatus() {
|
|
63
|
+
const cwd = process.cwd();
|
|
64
|
+
logger_1.logger.title('trustlocal status');
|
|
65
|
+
// ── 1. Read trustlocal.json ───────────────────────────────────────────────
|
|
66
|
+
const config = await (0, trustlocal_1.readConfig)(cwd);
|
|
67
|
+
if (!config) {
|
|
68
|
+
logger_1.logger.error('trustlocal.json not found.');
|
|
69
|
+
logger_1.logger.info('Run `npx trustlocal init` first.');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
// ── 2. Print basic info ───────────────────────────────────────────────────
|
|
73
|
+
logger_1.logger.info(`Framework : ${(0, framework_1.frameworkDisplayName)(config.framework)}`);
|
|
74
|
+
logger_1.logger.info(`Domains : ${config.domains.join(', ')}`);
|
|
75
|
+
logger_1.logger.info(`Cert dir : ${config.certDir}`);
|
|
76
|
+
logger_1.logger.blank();
|
|
77
|
+
// ── Cert expiry ───────────────────────────────────────────────────────────
|
|
78
|
+
const certPath = (0, path_1.join)(cwd, config.certDir, generate_1.CERT_FILENAME);
|
|
79
|
+
const certExists = await fileExists(certPath);
|
|
80
|
+
if (!certExists) {
|
|
81
|
+
statusLine('ERROR', 'Certificate file', 'Missing — run `npx trustlocal sync`');
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const expiry = (0, generate_1.getCertExpiry)(certPath);
|
|
85
|
+
const now = new Date();
|
|
86
|
+
const daysLeft = Math.floor((expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
|
87
|
+
const expiryStr = `${expiry.toISOString().split('T')[0]} (${daysLeft} days)`;
|
|
88
|
+
if (daysLeft < 0) {
|
|
89
|
+
statusLine('ERROR', 'Certificate expiry', `EXPIRED ${expiryStr}`);
|
|
90
|
+
}
|
|
91
|
+
else if (daysLeft < 30) {
|
|
92
|
+
statusLine('WARNING', 'Certificate expiry', `Expiring soon: ${expiryStr}`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
statusLine('OK', 'Certificate expiry', expiryStr);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// ── 3. Config injection check ─────────────────────────────────────────────
|
|
99
|
+
if (config.framework === 'express' || config.framework === 'plain') {
|
|
100
|
+
// Express/plain don't inject into a framework config file
|
|
101
|
+
statusLine('OK', 'Config injection', 'N/A (Express/plain — use .env)');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const configFile = config.configFiles[0];
|
|
105
|
+
if (!configFile) {
|
|
106
|
+
statusLine('WARNING', 'Config injection', 'No config file recorded');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const configPath = (0, path_1.join)(cwd, configFile);
|
|
110
|
+
const marker = getInjectionMarker(config.framework);
|
|
111
|
+
const hasInjection = await fileContains(configPath, marker);
|
|
112
|
+
if (hasInjection) {
|
|
113
|
+
statusLine('OK', 'Config injection', `Present in ${configFile}`);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
statusLine('WARNING', 'Config injection', `Not found in ${configFile} — run sync`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ── 4. NODE_EXTRA_CA_CERTS in .env ────────────────────────────────────────
|
|
121
|
+
const envPath = (0, path_1.join)(cwd, '.env');
|
|
122
|
+
const hasEnvKey = await fileContains(envPath, express_1.ENV_KEY);
|
|
123
|
+
if (hasEnvKey) {
|
|
124
|
+
statusLine('OK', 'NODE_EXTRA_CA_CERTS', 'Set in .env');
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
statusLine('WARNING', 'NODE_EXTRA_CA_CERTS', 'Not set in .env');
|
|
128
|
+
}
|
|
129
|
+
// ── 5. .gitignore check ───────────────────────────────────────────────────
|
|
130
|
+
const gitignorePath = (0, path_1.join)(cwd, '.gitignore');
|
|
131
|
+
const gitignoreOk = await fileContains(gitignorePath, config.certDir);
|
|
132
|
+
if (gitignoreOk) {
|
|
133
|
+
statusLine('OK', '.gitignore', `${config.certDir}/ excluded`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
statusLine('ERROR', '.gitignore', `${config.certDir}/ is NOT in .gitignore — private keys may be committed!`);
|
|
137
|
+
}
|
|
138
|
+
logger_1.logger.blank();
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx trustlocal sync`
|
|
3
|
+
*
|
|
4
|
+
* Execution flow (per spec §5.2):
|
|
5
|
+
* 1. Read trustlocal.json — exit with error if not found
|
|
6
|
+
* 2. Run mkcert -install on this machine
|
|
7
|
+
* 3. Regenerate certs for the same domains into .trustlocal/
|
|
8
|
+
* 4. Re-inject config (idempotent)
|
|
9
|
+
* 5. Set NODE_EXTRA_CA_CERTS in .env
|
|
10
|
+
* 6. Print success message
|
|
11
|
+
*/
|
|
12
|
+
export declare function runSync(): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA+DH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CA8C7C"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `npx trustlocal sync`
|
|
4
|
+
*
|
|
5
|
+
* Execution flow (per spec §5.2):
|
|
6
|
+
* 1. Read trustlocal.json — exit with error if not found
|
|
7
|
+
* 2. Run mkcert -install on this machine
|
|
8
|
+
* 3. Regenerate certs for the same domains into .trustlocal/
|
|
9
|
+
* 4. Re-inject config (idempotent)
|
|
10
|
+
* 5. Set NODE_EXTRA_CA_CERTS in .env
|
|
11
|
+
* 6. Print success message
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.runSync = runSync;
|
|
15
|
+
const promises_1 = require("fs/promises");
|
|
16
|
+
const path_1 = require("path");
|
|
17
|
+
const logger_1 = require("../utils/logger");
|
|
18
|
+
const trustlocal_1 = require("../config/trustlocal");
|
|
19
|
+
const check_1 = require("../mkcert/check");
|
|
20
|
+
const install_1 = require("../mkcert/install");
|
|
21
|
+
const generate_1 = require("../mkcert/generate");
|
|
22
|
+
const nextjs_1 = require("../injectors/nextjs");
|
|
23
|
+
const vite_1 = require("../injectors/vite");
|
|
24
|
+
const express_1 = require("../injectors/express");
|
|
25
|
+
const nginx_1 = require("../injectors/nginx");
|
|
26
|
+
const plain_1 = require("../injectors/plain");
|
|
27
|
+
async function ensureNodeExtraCA(cwd, caRootPem) {
|
|
28
|
+
const envPath = (0, path_1.join)(cwd, '.env');
|
|
29
|
+
let content = '';
|
|
30
|
+
try {
|
|
31
|
+
content = await (0, promises_1.readFile)(envPath, 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// file missing — create it
|
|
35
|
+
}
|
|
36
|
+
if (content.includes('NODE_EXTRA_CA_CERTS'))
|
|
37
|
+
return;
|
|
38
|
+
const line = `\n# trustlocal — allow Node.js to trust the local CA\nNODE_EXTRA_CA_CERTS=${caRootPem}\n`;
|
|
39
|
+
await (0, promises_1.writeFile)(envPath, content + line, 'utf-8');
|
|
40
|
+
}
|
|
41
|
+
async function runInjector(framework, configFile, cwd, caRootPem) {
|
|
42
|
+
switch (framework) {
|
|
43
|
+
case 'nextjs': {
|
|
44
|
+
const result = await (0, nextjs_1.injectNextjs)((0, path_1.join)(cwd, configFile ?? 'next.config.js'));
|
|
45
|
+
if (!result.alreadyConfigured)
|
|
46
|
+
logger_1.logger.success('Next.js config updated');
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'vite': {
|
|
50
|
+
const result = await (0, vite_1.injectVite)((0, path_1.join)(cwd, configFile ?? 'vite.config.ts'));
|
|
51
|
+
if (!result.alreadyConfigured)
|
|
52
|
+
logger_1.logger.success('Vite config updated');
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'express':
|
|
56
|
+
await (0, express_1.injectExpress)((0, path_1.join)(cwd, '.env'), caRootPem);
|
|
57
|
+
logger_1.logger.success('NODE_EXTRA_CA_CERTS set in .env');
|
|
58
|
+
(0, express_1.printExpressSnippet)('.trustlocal');
|
|
59
|
+
break;
|
|
60
|
+
case 'nginx': {
|
|
61
|
+
const result = await (0, nginx_1.injectNginx)((0, path_1.join)(cwd, configFile ?? 'nginx.conf'));
|
|
62
|
+
if (!result.alreadyConfigured)
|
|
63
|
+
logger_1.logger.success('nginx.conf updated');
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'plain':
|
|
67
|
+
(0, plain_1.printPlainInstructions)('.trustlocal');
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function runSync() {
|
|
72
|
+
const cwd = process.cwd();
|
|
73
|
+
logger_1.logger.title('trustlocal sync');
|
|
74
|
+
// ── 1. Read trustlocal.json ───────────────────────────────────────────────
|
|
75
|
+
const config = await (0, trustlocal_1.readConfig)(cwd);
|
|
76
|
+
if (!config) {
|
|
77
|
+
logger_1.logger.error('trustlocal.json not found.');
|
|
78
|
+
logger_1.logger.info('Run `npx trustlocal init` first to set up HTTPS for this project.');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
// ── 2. Check / install mkcert ─────────────────────────────────────────────
|
|
82
|
+
logger_1.logger.step('Checking mkcert...');
|
|
83
|
+
const mkcertInfo = (0, check_1.checkMkcert)();
|
|
84
|
+
if (!mkcertInfo.installed) {
|
|
85
|
+
logger_1.logger.warn('mkcert not found — attempting auto-install...');
|
|
86
|
+
(0, install_1.installMkcert)();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
logger_1.logger.success(`mkcert ${mkcertInfo.version ?? ''} found`);
|
|
90
|
+
}
|
|
91
|
+
logger_1.logger.step('Installing local CA (may prompt for sudo)...');
|
|
92
|
+
(0, generate_1.installCA)();
|
|
93
|
+
logger_1.logger.success('Local CA registered');
|
|
94
|
+
// ── 3. Regenerate certs ────────────────────────────────────────────────────
|
|
95
|
+
logger_1.logger.step(`Generating certificates for: ${config.domains.join(', ')}`);
|
|
96
|
+
await (0, generate_1.generateCerts)(config.certDir, config.domains, cwd);
|
|
97
|
+
logger_1.logger.success(`Certificates generated → ${config.certDir}/`);
|
|
98
|
+
// ── 4. Re-inject config (idempotent) ──────────────────────────────────────
|
|
99
|
+
logger_1.logger.step('Checking framework config...');
|
|
100
|
+
const caRootPem = `${(0, check_1.getMkcertCARoot)()}/rootCA.pem`;
|
|
101
|
+
await runInjector(config.framework, config.configFiles[0], cwd, caRootPem);
|
|
102
|
+
logger_1.logger.success('Config verified');
|
|
103
|
+
// ── 5. NODE_EXTRA_CA_CERTS ────────────────────────────────────────────────
|
|
104
|
+
logger_1.logger.step('Updating .env...');
|
|
105
|
+
await ensureNodeExtraCA(cwd, caRootPem);
|
|
106
|
+
logger_1.logger.success('NODE_EXTRA_CA_CERTS set');
|
|
107
|
+
logger_1.logger.blank();
|
|
108
|
+
logger_1.logger.success('Done! HTTPS is ready on this machine.');
|
|
109
|
+
logger_1.logger.blank();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* trustlocal.json reader / writer
|
|
3
|
+
*
|
|
4
|
+
* This file is committed to the project repo. It contains NO secrets —
|
|
5
|
+
* only metadata needed for teammates to reproduce the setup.
|
|
6
|
+
*/
|
|
7
|
+
import type { Framework } from '../detector/framework';
|
|
8
|
+
export declare const CONFIG_FILENAME = "trustlocal.json";
|
|
9
|
+
export declare const CERT_DIR = ".trustlocal";
|
|
10
|
+
export interface TrustlocalConfig {
|
|
11
|
+
/** Schema version — currently always "1" */
|
|
12
|
+
version: '1';
|
|
13
|
+
framework: Framework;
|
|
14
|
+
domains: string[];
|
|
15
|
+
/** Relative path from project root to the cert directory */
|
|
16
|
+
certDir: string;
|
|
17
|
+
/** Config files that were injected (relative paths) */
|
|
18
|
+
configFiles: string[];
|
|
19
|
+
createdAt: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read and parse trustlocal.json from the project root.
|
|
23
|
+
* Returns null if the file does not exist.
|
|
24
|
+
* Throws if the file exists but is malformed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readConfig(cwd: string): Promise<TrustlocalConfig | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Write trustlocal.json to the project root.
|
|
29
|
+
*/
|
|
30
|
+
export declare function writeConfig(cwd: string, config: TrustlocalConfig): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Build a new TrustlocalConfig from the given parameters.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildConfig(params: {
|
|
35
|
+
framework: Framework;
|
|
36
|
+
domains: string[];
|
|
37
|
+
certDir?: string;
|
|
38
|
+
configFiles: string[];
|
|
39
|
+
}): TrustlocalConfig;
|
|
40
|
+
//# sourceMappingURL=trustlocal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trustlocal.d.ts","sourceRoot":"","sources":["../../src/config/trustlocal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,eAAO,MAAM,eAAe,oBAAoB,CAAC;AACjD,eAAO,MAAM,QAAQ,gBAAgB,CAAC;AAEtC,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAS9E;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GAAG,gBAAgB,CASnB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* trustlocal.json reader / writer
|
|
4
|
+
*
|
|
5
|
+
* This file is committed to the project repo. It contains NO secrets —
|
|
6
|
+
* only metadata needed for teammates to reproduce the setup.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CERT_DIR = exports.CONFIG_FILENAME = void 0;
|
|
10
|
+
exports.readConfig = readConfig;
|
|
11
|
+
exports.writeConfig = writeConfig;
|
|
12
|
+
exports.buildConfig = buildConfig;
|
|
13
|
+
const promises_1 = require("fs/promises");
|
|
14
|
+
const path_1 = require("path");
|
|
15
|
+
exports.CONFIG_FILENAME = 'trustlocal.json';
|
|
16
|
+
exports.CERT_DIR = '.trustlocal';
|
|
17
|
+
/**
|
|
18
|
+
* Read and parse trustlocal.json from the project root.
|
|
19
|
+
* Returns null if the file does not exist.
|
|
20
|
+
* Throws if the file exists but is malformed.
|
|
21
|
+
*/
|
|
22
|
+
async function readConfig(cwd) {
|
|
23
|
+
const configPath = (0, path_1.join)(cwd, exports.CONFIG_FILENAME);
|
|
24
|
+
try {
|
|
25
|
+
const raw = await (0, promises_1.readFile)(configPath, 'utf-8');
|
|
26
|
+
return JSON.parse(raw);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (err.code === 'ENOENT')
|
|
30
|
+
return null;
|
|
31
|
+
throw new Error(`Failed to parse ${exports.CONFIG_FILENAME}: ${String(err)}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write trustlocal.json to the project root.
|
|
36
|
+
*/
|
|
37
|
+
async function writeConfig(cwd, config) {
|
|
38
|
+
const configPath = (0, path_1.join)(cwd, exports.CONFIG_FILENAME);
|
|
39
|
+
await (0, promises_1.writeFile)(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build a new TrustlocalConfig from the given parameters.
|
|
43
|
+
*/
|
|
44
|
+
function buildConfig(params) {
|
|
45
|
+
return {
|
|
46
|
+
version: '1',
|
|
47
|
+
framework: params.framework,
|
|
48
|
+
domains: params.domains,
|
|
49
|
+
certDir: params.certDir ?? exports.CERT_DIR,
|
|
50
|
+
configFiles: params.configFiles,
|
|
51
|
+
createdAt: new Date().toISOString(),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=trustlocal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trustlocal.js","sourceRoot":"","sources":["../../src/config/trustlocal.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA0BH,gCASC;AAKD,kCAGC;AAKD,kCAcC;AA5DD,0CAAkD;AAClD,+BAA4B;AAGf,QAAA,eAAe,GAAG,iBAAiB,CAAC;AACpC,QAAA,QAAQ,GAAG,aAAa,CAAC;AActC;;;;GAIG;AACI,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,uBAAe,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAA,mBAAQ,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,mBAAmB,uBAAe,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,MAAwB;IACrE,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,uBAAe,CAAC,CAAC;IAC9C,MAAM,IAAA,oBAAS,EAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,MAK3B;IACC,OAAO;QACL,OAAO,EAAE,GAAG;QACZ,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,gBAAQ;QACnC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type Framework = 'nextjs' | 'vite' | 'express' | 'nginx' | 'plain';
|
|
2
|
+
export interface DetectionResult {
|
|
3
|
+
framework: Framework;
|
|
4
|
+
/** Relative path to the config file that will be injected, if applicable. */
|
|
5
|
+
configFile?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Detect the project framework by scanning package.json and the filesystem.
|
|
9
|
+
* Returns the framework type and the config file that should be injected into.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectFramework(cwd: string): Promise<DetectionResult>;
|
|
12
|
+
/** Human-readable name for display in the terminal. */
|
|
13
|
+
export declare function frameworkDisplayName(framework: Framework): string;
|
|
14
|
+
//# sourceMappingURL=framework.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework.d.ts","sourceRoot":"","sources":["../../src/detector/framework.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuCD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA0C3E;AAED,uDAAuD;AACvD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CASjE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectFramework = detectFramework;
|
|
4
|
+
exports.frameworkDisplayName = frameworkDisplayName;
|
|
5
|
+
const promises_1 = require("fs/promises");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
async function fileExists(filePath) {
|
|
8
|
+
try {
|
|
9
|
+
await (0, promises_1.access)(filePath);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function readPackageJson(cwd) {
|
|
17
|
+
try {
|
|
18
|
+
const content = await (0, promises_1.readFile)((0, path_1.join)(cwd, 'package.json'), 'utf-8');
|
|
19
|
+
return JSON.parse(content);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function hasDependency(pkg, name) {
|
|
26
|
+
return !!(pkg.dependencies?.[name] ?? pkg.devDependencies?.[name]);
|
|
27
|
+
}
|
|
28
|
+
/** Find the first existing file among candidates (relative to cwd). */
|
|
29
|
+
async function findFirstExisting(cwd, candidates) {
|
|
30
|
+
for (const candidate of candidates) {
|
|
31
|
+
if (await fileExists((0, path_1.join)(cwd, candidate))) {
|
|
32
|
+
return candidate;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Detect the project framework by scanning package.json and the filesystem.
|
|
39
|
+
* Returns the framework type and the config file that should be injected into.
|
|
40
|
+
*/
|
|
41
|
+
async function detectFramework(cwd) {
|
|
42
|
+
const pkg = await readPackageJson(cwd);
|
|
43
|
+
// ── Next.js ────────────────────────────────────────────────────────────────
|
|
44
|
+
if (pkg && hasDependency(pkg, 'next')) {
|
|
45
|
+
const configFile = await findFirstExisting(cwd, [
|
|
46
|
+
'next.config.ts',
|
|
47
|
+
'next.config.js',
|
|
48
|
+
'next.config.mjs',
|
|
49
|
+
]);
|
|
50
|
+
return { framework: 'nextjs', configFile: configFile ?? 'next.config.js' };
|
|
51
|
+
}
|
|
52
|
+
// ── Vite ──────────────────────────────────────────────────────────────────
|
|
53
|
+
if (pkg && hasDependency(pkg, 'vite')) {
|
|
54
|
+
const configFile = await findFirstExisting(cwd, [
|
|
55
|
+
'vite.config.ts',
|
|
56
|
+
'vite.config.js',
|
|
57
|
+
'vite.config.mts',
|
|
58
|
+
'vite.config.mjs',
|
|
59
|
+
]);
|
|
60
|
+
return { framework: 'vite', configFile: configFile ?? 'vite.config.ts' };
|
|
61
|
+
}
|
|
62
|
+
// ── Express / Node ─────────────────────────────────────────────────────────
|
|
63
|
+
if (pkg && hasDependency(pkg, 'express')) {
|
|
64
|
+
const serverFile = await findFirstExisting(cwd, ['server.ts', 'server.js', 'app.ts', 'app.js']);
|
|
65
|
+
return { framework: 'express', configFile: serverFile };
|
|
66
|
+
}
|
|
67
|
+
// server.js without express in package.json
|
|
68
|
+
if (await fileExists((0, path_1.join)(cwd, 'server.js'))) {
|
|
69
|
+
return { framework: 'express', configFile: 'server.js' };
|
|
70
|
+
}
|
|
71
|
+
// ── Nginx ──────────────────────────────────────────────────────────────────
|
|
72
|
+
if (await fileExists((0, path_1.join)(cwd, 'nginx.conf'))) {
|
|
73
|
+
return { framework: 'nginx', configFile: 'nginx.conf' };
|
|
74
|
+
}
|
|
75
|
+
// ── Plain fallback ─────────────────────────────────────────────────────────
|
|
76
|
+
return { framework: 'plain' };
|
|
77
|
+
}
|
|
78
|
+
/** Human-readable name for display in the terminal. */
|
|
79
|
+
function frameworkDisplayName(framework) {
|
|
80
|
+
const names = {
|
|
81
|
+
nextjs: 'Next.js',
|
|
82
|
+
vite: 'Vite',
|
|
83
|
+
express: 'Express / Node',
|
|
84
|
+
nginx: 'Nginx',
|
|
85
|
+
plain: 'Plain (no framework detected)',
|
|
86
|
+
};
|
|
87
|
+
return names[framework];
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=framework.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework.js","sourceRoot":"","sources":["../../src/detector/framework.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* trustlocal — One command. HTTPS everywhere. Zero config.
|
|
5
|
+
*
|
|
6
|
+
* CLI entry point. Sets up commander with all four sub-commands.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const commander_1 = require("commander");
|
|
10
|
+
const init_1 = require("./commands/init");
|
|
11
|
+
const sync_1 = require("./commands/sync");
|
|
12
|
+
const renew_1 = require("./commands/renew");
|
|
13
|
+
const status_1 = require("./commands/status");
|
|
14
|
+
const program = new commander_1.Command();
|
|
15
|
+
program
|
|
16
|
+
.name('trustlocal')
|
|
17
|
+
.description('Automate local HTTPS setup using mkcert. One command — certs generated, framework configured, teammates synced.')
|
|
18
|
+
.version('0.1.0');
|
|
19
|
+
// ── init ─────────────────────────────────────────────────────────────────────
|
|
20
|
+
program
|
|
21
|
+
.command('init')
|
|
22
|
+
.description('Set up local HTTPS for this project.\n' +
|
|
23
|
+
' Installs mkcert if needed, detects your framework, generates trusted certs,\n' +
|
|
24
|
+
' injects HTTPS config, and writes trustlocal.json for teammates to use.')
|
|
25
|
+
.option('--domains <domains>', 'Comma-separated extra domains to include (e.g. myapp.local)', (val) => val.split(',').map((d) => d.trim()))
|
|
26
|
+
.option('--force', 'Re-initialise even if trustlocal.json already exists')
|
|
27
|
+
.option('--dry-run', 'Preview what would happen without writing any files')
|
|
28
|
+
.action(async (opts) => {
|
|
29
|
+
await (0, init_1.runInit)({
|
|
30
|
+
domains: opts.domains,
|
|
31
|
+
force: opts.force,
|
|
32
|
+
dryRun: opts.dryRun,
|
|
33
|
+
}).catch(handleError);
|
|
34
|
+
});
|
|
35
|
+
// ── sync ──────────────────────────────────────────────────────────────────────
|
|
36
|
+
program
|
|
37
|
+
.command('sync')
|
|
38
|
+
.description('Set up HTTPS on a new machine for an existing project.\n' +
|
|
39
|
+
' Reads trustlocal.json, generates fresh certs (no key sharing),\n' +
|
|
40
|
+
' and re-injects config identically. Run after cloning a repo.')
|
|
41
|
+
.action(async () => {
|
|
42
|
+
await (0, sync_1.runSync)().catch(handleError);
|
|
43
|
+
});
|
|
44
|
+
// ── renew ─────────────────────────────────────────────────────────────────────
|
|
45
|
+
program
|
|
46
|
+
.command('renew')
|
|
47
|
+
.description('Renew expiring certificates.\n' +
|
|
48
|
+
' Certificates expire after 2 years. Deletes old certs and generates fresh ones.\n' +
|
|
49
|
+
' Config files are not touched — cert paths remain the same.')
|
|
50
|
+
.option('--force', 'Renew even if the cert has more than 30 days remaining')
|
|
51
|
+
.action(async (opts) => {
|
|
52
|
+
await (0, renew_1.runRenew)({ force: opts.force }).catch(handleError);
|
|
53
|
+
});
|
|
54
|
+
// ── status ────────────────────────────────────────────────────────────────────
|
|
55
|
+
program
|
|
56
|
+
.command('status')
|
|
57
|
+
.description('Show the current HTTPS setup status for this project.\n' +
|
|
58
|
+
' Checks cert expiry, config injection, NODE_EXTRA_CA_CERTS, and .gitignore.\n' +
|
|
59
|
+
' Prints OK / WARNING / ERROR for each check.')
|
|
60
|
+
.action(async () => {
|
|
61
|
+
await (0, status_1.runStatus)().catch(handleError);
|
|
62
|
+
});
|
|
63
|
+
function handleError(err) {
|
|
64
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
65
|
+
console.error(`\n ✗ ${message}\n`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
program.parse(process.argv);
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA;;;;GAIG;;AAEH,yCAAoC;AACpC,0CAA0C;AAC1C,0CAA0C;AAC1C,4CAA4C;AAC5C,8CAA8C;AAE9C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,iHAAiH,CAAC;KAC9H,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,gFAAgF;AAChF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CACV,wCAAwC;IACxC,iFAAiF;IACjF,0EAA0E,CAC3E;KACA,MAAM,CAAC,qBAAqB,EAAE,6DAA6D,EAAE,CAAC,GAAG,EAAE,EAAE,CACpG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CACpC;KACA,MAAM,CAAC,SAAS,EAAE,sDAAsD,CAAC;KACzE,MAAM,CAAC,WAAW,EAAE,qDAAqD,CAAC;KAC1E,MAAM,CAAC,KAAK,EAAE,IAA+D,EAAE,EAAE;IAChF,MAAM,IAAA,cAAO,EAAC;QACZ,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CACV,0DAA0D;IAC1D,oEAAoE;IACpE,gEAAgE,CACjE;KACA,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAA,cAAO,GAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CACV,gCAAgC;IAChC,oFAAoF;IACpF,8DAA8D,CAC/D;KACA,MAAM,CAAC,SAAS,EAAE,wDAAwD,CAAC;KAC3E,MAAM,CAAC,KAAK,EAAE,IAAyB,EAAE,EAAE;IAC1C,MAAM,IAAA,gBAAQ,EAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CACV,yDAAyD;IACzD,gFAAgF;IAChF,+CAA+C,CAChD;KACA,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAA,kBAAS,GAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEL,SAAS,WAAW,CAAC,GAAY;IAC/B,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight AST helpers for reading JavaScript/TypeScript config files.
|
|
3
|
+
*
|
|
4
|
+
* Uses @babel/parser for parsing only — no @babel/generator dependency.
|
|
5
|
+
* Injection is done by precise string-slice insertion at AST-located positions,
|
|
6
|
+
* which preserves the original file's formatting.
|
|
7
|
+
*/
|
|
8
|
+
import type { File, ObjectExpression, Node } from '@babel/types';
|
|
9
|
+
/** Deep-first search for nodes matching a predicate. */
|
|
10
|
+
export declare function findNodes<T extends Node>(root: Node, predicate: (node: Node) => node is T): T[];
|
|
11
|
+
/** Parse a JS/TS source string into a Babel AST. */
|
|
12
|
+
export declare function parseSource(source: string): File;
|
|
13
|
+
/** Check if an ObjectExpression already has a direct property with the given key. */
|
|
14
|
+
export declare function hasProperty(obj: ObjectExpression, key: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Get the character position immediately after the opening `{` of an
|
|
17
|
+
* ObjectExpression so we can insert properties at the top.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getObjectOpenBraceEnd(obj: ObjectExpression, source: string): number;
|
|
20
|
+
/**
|
|
21
|
+
* Find the top-level exported config ObjectExpression.
|
|
22
|
+
*
|
|
23
|
+
* Handles:
|
|
24
|
+
* - `export default { ... }`
|
|
25
|
+
* - `export default defineConfig({ ... })`
|
|
26
|
+
* - `module.exports = { ... }`
|
|
27
|
+
* - `const config = { ... }` (last top-level ObjectExpression as fallback)
|
|
28
|
+
*/
|
|
29
|
+
export declare function findTopLevelConfigObject(ast: File): ObjectExpression | null;
|
|
30
|
+
/**
|
|
31
|
+
* Check whether a nested path like `server.https` already exists inside an
|
|
32
|
+
* ObjectExpression. `path` is given as an array of key names.
|
|
33
|
+
*/
|
|
34
|
+
export declare function hasNestedProperty(obj: ObjectExpression, path: string[]): boolean;
|
|
35
|
+
//# sourceMappingURL=astHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astHelper.d.ts","sourceRoot":"","sources":["../../src/injectors/astHelper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,IAAI,EACJ,gBAAgB,EAOhB,IAAI,EACL,MAAM,cAAc,CAAC;AAuBtB,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,CAAC,SAAS,IAAI,EACtC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,GACnC,CAAC,EAAE,CASL;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAWhD;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAOvE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,IAAI,GAAG,gBAAgB,GAAG,IAAI,CAoD3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAkBhF"}
|