@cliftonc/cfld 0.2.6 → 0.2.7

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.
Files changed (2) hide show
  1. package/dist/cli.js +56 -39
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3,15 +3,16 @@
3
3
  // src/cli.ts
4
4
  import { parseArgs } from "util";
5
5
  import { readFileSync as readFileSync7, realpathSync } from "fs";
6
- import { dirname, join as join8 } from "path";
6
+ import { dirname as dirname2, join as join9 } from "path";
7
7
  import { fileURLToPath } from "url";
8
8
  import pc7 from "picocolors";
9
9
 
10
10
  // src/commands/run.ts
11
- import { join as join6 } from "path";
11
+ import { join as join7 } from "path";
12
12
 
13
13
  // src/core/state-machine.ts
14
- import { existsSync as existsSync2 } from "fs";
14
+ import { copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync, unlinkSync } from "fs";
15
+ import { dirname, join as join2 } from "path";
15
16
 
16
17
  // src/util/paths.ts
17
18
  import { homedir } from "os";
@@ -229,7 +230,8 @@ function cfargoTunnelUuid(target) {
229
230
  import { writeFileSync } from "fs";
230
231
  function renderIngressConfig(cfg) {
231
232
  const rules = cfg.routes.flatMap((r) => {
232
- const lines = [` - hostname: ${r.hostname}`];
233
+ const host = r.hostname.startsWith("*") ? JSON.stringify(r.hostname) : r.hostname;
234
+ const lines = [` - hostname: ${host}`];
233
235
  if (r.path) lines.push(` path: ${r.path}`);
234
236
  lines.push(` service: http://localhost:${r.port}`);
235
237
  return lines;
@@ -300,15 +302,17 @@ async function reconcile(input, events = {}) {
300
302
  let created = false;
301
303
  if (existing) {
302
304
  uuid = existing.id;
303
- if (!existsSync2(credentialsPath(uuid))) {
304
- step2("Refetching tunnel credentials");
305
- await fetchToken(tunnelName, credentialsPath(uuid), certPath);
306
- }
307
305
  } else {
308
306
  step2(`Creating tunnel ${tunnelName}`);
309
307
  uuid = await createTunnel(tunnelName, certPath);
310
308
  created = true;
311
309
  }
310
+ if (!existsSync2(credentialsPath(uuid))) {
311
+ if (!adoptCredentialsBesideCert(uuid, certPath)) {
312
+ step2("Refetching tunnel credentials");
313
+ await fetchToken(tunnelName, credentialsPath(uuid), certPath);
314
+ }
315
+ }
312
316
  const prior = getEntry(tunnelName);
313
317
  const owned = /* @__PURE__ */ new Set([
314
318
  prior?.hostname,
@@ -358,9 +362,22 @@ async function reconcile(input, events = {}) {
358
362
  function nowIso() {
359
363
  return (/* @__PURE__ */ new Date()).toISOString();
360
364
  }
365
+ function adoptCredentialsBesideCert(uuid, certPath) {
366
+ const beside = join2(dirname(certPath), `${uuid}.json`);
367
+ const target = credentialsPath(uuid);
368
+ if (beside === target || !existsSync2(beside)) return false;
369
+ mkdirSync2(dirname(target), { recursive: true });
370
+ try {
371
+ renameSync(beside, target);
372
+ } catch {
373
+ copyFileSync(beside, target);
374
+ unlinkSync(beside);
375
+ }
376
+ return true;
377
+ }
361
378
 
362
379
  // src/core/cert-store.ts
363
- import { copyFileSync, existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync } from "fs";
380
+ import { copyFileSync as copyFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync } from "fs";
364
381
 
365
382
  // src/core/cert.ts
366
383
  import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
@@ -413,7 +430,7 @@ async function certZoneName(certPath) {
413
430
 
414
431
  // src/core/cert-store.ts
415
432
  function ensureStoreDir() {
416
- mkdirSync2(certStoreDir(), { recursive: true });
433
+ mkdirSync3(certStoreDir(), { recursive: true });
417
434
  }
418
435
  function storedCertForZone(zone) {
419
436
  const p = certPathForZone(zone);
@@ -443,19 +460,19 @@ function resolveCert(zone) {
443
460
  function importCert(zone, fromPath = defaultCertPath()) {
444
461
  ensureStoreDir();
445
462
  const dest = certPathForZone(zone);
446
- copyFileSync(fromPath, dest);
463
+ copyFileSync2(fromPath, dest);
447
464
  return dest;
448
465
  }
449
466
 
450
467
  // src/core/hostname.ts
451
468
  import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
452
- import { basename, join as join2 } from "path";
469
+ import { basename, join as join3 } from "path";
453
470
  function slugify(input) {
454
471
  return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
455
472
  }
456
473
  function deriveSlug(cwd, nameFlag) {
457
474
  if (nameFlag) return slugify(nameFlag);
458
- const pkgPath = join2(cwd, "package.json");
475
+ const pkgPath = join3(cwd, "package.json");
459
476
  if (existsSync5(pkgPath)) {
460
477
  try {
461
478
  const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
@@ -541,12 +558,12 @@ function findFreePort() {
541
558
 
542
559
  // src/core/project-config.ts
543
560
  import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
544
- import { join as join3 } from "path";
561
+ import { join as join4 } from "path";
545
562
  function dotConfigPath(cwd) {
546
- return join3(cwd, PROJECT_CONFIG_FILE);
563
+ return join4(cwd, PROJECT_CONFIG_FILE);
547
564
  }
548
565
  function readAuthored(cwd) {
549
- const pkgPath = join3(cwd, "package.json");
566
+ const pkgPath = join4(cwd, "package.json");
550
567
  if (!existsSync6(pkgPath)) return void 0;
551
568
  try {
552
569
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
@@ -965,8 +982,8 @@ function colorLevel(level) {
965
982
 
966
983
  // src/commands/login.ts
967
984
  import { spawn as spawn4 } from "child_process";
968
- import { copyFileSync as copyFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync3, renameSync, rmSync } from "fs";
969
- import { join as join4 } from "path";
985
+ import { copyFileSync as copyFileSync3, existsSync as existsSync8, mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync } from "fs";
986
+ import { join as join5 } from "path";
970
987
 
971
988
  // src/ui/prompts.ts
972
989
  async function clack() {
@@ -1086,7 +1103,7 @@ async function runLogin() {
1086
1103
  const bin = await resolveBinary();
1087
1104
  const def = defaultCertPath();
1088
1105
  const backup = existsSync8(def) ? `${def}.cfld-backup` : void 0;
1089
- if (backup) renameSync(def, backup);
1106
+ if (backup) renameSync2(def, backup);
1090
1107
  try {
1091
1108
  step("Opening your browser to authorize with Cloudflare (no API token needed)\u2026");
1092
1109
  note(" Pick the domain you want to use. Waiting for you to finish\u2026");
@@ -1105,13 +1122,13 @@ async function runLogin() {
1105
1122
  );
1106
1123
  }
1107
1124
  if (!backup) return def;
1108
- mkdirSync3(cfldDir(), { recursive: true });
1109
- const fresh = join4(cfldDir(), "login-cert.tmp");
1110
- copyFileSync2(def, fresh);
1125
+ mkdirSync4(cfldDir(), { recursive: true });
1126
+ const fresh = join5(cfldDir(), "login-cert.tmp");
1127
+ copyFileSync3(def, fresh);
1111
1128
  rmSync(def);
1112
1129
  return fresh;
1113
1130
  } finally {
1114
- if (backup) renameSync(backup, def);
1131
+ if (backup) renameSync2(backup, def);
1115
1132
  }
1116
1133
  }
1117
1134
  function discardLoginCert(certPath) {
@@ -1212,11 +1229,11 @@ function printZeroZoneGuidance() {
1212
1229
 
1213
1230
  // src/util/gitignore.ts
1214
1231
  import { existsSync as existsSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
1215
- import { join as join5 } from "path";
1232
+ import { join as join6 } from "path";
1216
1233
  function ensureGitignored(cwd, pattern) {
1217
- const gitignorePath = join5(cwd, ".gitignore");
1234
+ const gitignorePath = join6(cwd, ".gitignore");
1218
1235
  const hasGitignore = existsSync9(gitignorePath);
1219
- const inRepo = hasGitignore || existsSync9(join5(cwd, ".git"));
1236
+ const inRepo = hasGitignore || existsSync9(join6(cwd, ".git"));
1220
1237
  if (!inRepo) return false;
1221
1238
  const existing = hasGitignore ? readFileSync6(gitignorePath, "utf8") : "";
1222
1239
  const present = existing.split("\n").map((l) => l.trim()).includes(pattern);
@@ -1465,7 +1482,7 @@ ${opts.reason}`);
1465
1482
  if (!up) warn(`Nothing is listening on :${ctx.port} yet \u2014 going live anyway.`);
1466
1483
  }
1467
1484
  if (!ctx.noEnv) {
1468
- const { changed } = upsertEnv(join6(ctx.cwd, ".env"), ctx.envKey, url);
1485
+ const { changed } = upsertEnv(join7(ctx.cwd, ".env"), ctx.envKey, url);
1469
1486
  if (changed && !dashboard) info(`Wrote ${ctx.envKey}=${url} to .env`);
1470
1487
  }
1471
1488
  if (dashboard) {
@@ -2092,9 +2109,9 @@ function resolveCurrentEntry2() {
2092
2109
  import pc5 from "picocolors";
2093
2110
 
2094
2111
  // src/core/service.ts
2095
- import { existsSync as existsSync10, mkdirSync as mkdirSync4, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
2112
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
2096
2113
  import { homedir as homedir2, platform } from "os";
2097
- import { join as join7 } from "path";
2114
+ import { join as join8 } from "path";
2098
2115
  function serviceSlug(name) {
2099
2116
  return name.replace(/^cfld-/, "");
2100
2117
  }
@@ -2102,16 +2119,16 @@ function launchAgentLabel(name) {
2102
2119
  return `com.cfld.${serviceSlug(name)}`;
2103
2120
  }
2104
2121
  function launchAgentPath(name) {
2105
- return join7(homedir2(), "Library", "LaunchAgents", `${launchAgentLabel(name)}.plist`);
2122
+ return join8(homedir2(), "Library", "LaunchAgents", `${launchAgentLabel(name)}.plist`);
2106
2123
  }
2107
2124
  function systemdUnitName(name) {
2108
2125
  return `cfld-${serviceSlug(name)}.service`;
2109
2126
  }
2110
2127
  function systemdUnitPath(name) {
2111
- return join7(homedir2(), ".config", "systemd", "user", systemdUnitName(name));
2128
+ return join8(homedir2(), ".config", "systemd", "user", systemdUnitName(name));
2112
2129
  }
2113
2130
  function logDir() {
2114
- return join7(cfldDir(), "logs");
2131
+ return join8(cfldDir(), "logs");
2115
2132
  }
2116
2133
  function renderLaunchAgent(spec) {
2117
2134
  const args = [
@@ -2125,8 +2142,8 @@ function renderLaunchAgent(spec) {
2125
2142
  spec.name
2126
2143
  ];
2127
2144
  const argsXml = args.map((a) => ` <string>${escapeXml(a)}</string>`).join("\n");
2128
- const out = join7(logDir(), `${serviceSlug(spec.name)}.out.log`);
2129
- const err = join7(logDir(), `${serviceSlug(spec.name)}.err.log`);
2145
+ const out = join8(logDir(), `${serviceSlug(spec.name)}.out.log`);
2146
+ const err = join8(logDir(), `${serviceSlug(spec.name)}.err.log`);
2130
2147
  return `<?xml version="1.0" encoding="UTF-8"?>
2131
2148
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
2132
2149
  <plist version="1.0">
@@ -2191,10 +2208,10 @@ function assertSupported() {
2191
2208
  }
2192
2209
  async function installService(spec) {
2193
2210
  const p = assertSupported();
2194
- mkdirSync4(logDir(), { recursive: true });
2211
+ mkdirSync5(logDir(), { recursive: true });
2195
2212
  if (p === "darwin") {
2196
2213
  const path = launchAgentPath(spec.name);
2197
- mkdirSync4(join7(homedir2(), "Library", "LaunchAgents"), { recursive: true });
2214
+ mkdirSync5(join8(homedir2(), "Library", "LaunchAgents"), { recursive: true });
2198
2215
  writeFileSync6(path, renderLaunchAgent(spec), "utf8");
2199
2216
  await exec("launchctl", ["unload", path]);
2200
2217
  const res = await exec("launchctl", ["load", "-w", path]);
@@ -2206,7 +2223,7 @@ async function installService(spec) {
2206
2223
  }
2207
2224
  } else {
2208
2225
  const path = systemdUnitPath(spec.name);
2209
- mkdirSync4(join7(homedir2(), ".config", "systemd", "user"), { recursive: true });
2226
+ mkdirSync5(join8(homedir2(), ".config", "systemd", "user"), { recursive: true });
2210
2227
  writeFileSync6(path, renderSystemdUnit(spec), "utf8");
2211
2228
  await exec("systemctl", ["--user", "daemon-reload"]);
2212
2229
  const res = await exec("systemctl", [
@@ -2371,8 +2388,8 @@ async function doctorCommand() {
2371
2388
  // src/cli.ts
2372
2389
  function readVersion() {
2373
2390
  try {
2374
- const here = dirname(fileURLToPath(import.meta.url));
2375
- const pkg = JSON.parse(readFileSync7(join8(here, "../package.json"), "utf8"));
2391
+ const here = dirname2(fileURLToPath(import.meta.url));
2392
+ const pkg = JSON.parse(readFileSync7(join9(here, "../package.json"), "utf8"));
2376
2393
  return typeof pkg.version === "string" ? pkg.version : "0.0.0";
2377
2394
  } catch {
2378
2395
  return "0.0.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cliftonc/cfld",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Zero-token, persistent Cloudflare tunnel CLI for local dev — same public HTTPS URL every run.",
5
5
  "type": "module",
6
6
  "bin": {