hatchkit 0.2.3 → 0.2.4
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/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +93 -12
- package/dist/config.js.map +1 -1
- package/dist/index.js +103 -29
- package/dist/index.js.map +1 -1
- package/dist/provision/index.d.ts +8 -0
- package/dist/provision/index.d.ts.map +1 -1
- package/dist/provision/index.js +303 -51
- package/dist/provision/index.js.map +1 -1
- package/dist/provision/search-console.d.ts +12 -9
- package/dist/provision/search-console.d.ts.map +1 -1
- package/dist/provision/search-console.js +36 -20
- package/dist/provision/search-console.js.map +1 -1
- package/dist/utils/cloudflare-api.d.ts.map +1 -1
- package/dist/utils/cloudflare-api.js +32 -17
- package/dist/utils/cloudflare-api.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -418,6 +418,13 @@ function flagValue(name) {
|
|
|
418
418
|
}
|
|
419
419
|
return undefined;
|
|
420
420
|
}
|
|
421
|
+
function provisionSurfaceModeFromManifest(manifest) {
|
|
422
|
+
if (manifest?.surfaces === "server-only")
|
|
423
|
+
return "server-only";
|
|
424
|
+
if (manifest?.surfaces === "client-only")
|
|
425
|
+
return "client-only";
|
|
426
|
+
return "shared";
|
|
427
|
+
}
|
|
421
428
|
/** Resolve the GitHub `owner/repo` slug from the cwd's git origin.
|
|
422
429
|
* Returns undefined when no remote is set or it's not a GitHub URL. */
|
|
423
430
|
async function detectRepoSlug() {
|
|
@@ -537,7 +544,6 @@ function servicesImpossibleForProject(manifest) {
|
|
|
537
544
|
return blocked;
|
|
538
545
|
if (!manifest.domain) {
|
|
539
546
|
blocked.add("email");
|
|
540
|
-
blocked.add("search-console");
|
|
541
547
|
}
|
|
542
548
|
if (manifest.surfaces === "server-only")
|
|
543
549
|
blocked.add("plausible");
|
|
@@ -549,6 +555,28 @@ function servicesImpossibleForProject(manifest) {
|
|
|
549
555
|
blocked.add("s3");
|
|
550
556
|
return blocked;
|
|
551
557
|
}
|
|
558
|
+
function addPositionals(rawArgs) {
|
|
559
|
+
const valueFlags = new Set([
|
|
560
|
+
"--server-dir",
|
|
561
|
+
"--client-dir",
|
|
562
|
+
"--project-dir",
|
|
563
|
+
"--domain",
|
|
564
|
+
"--name",
|
|
565
|
+
"--surfaces",
|
|
566
|
+
]);
|
|
567
|
+
const positional = [];
|
|
568
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
569
|
+
const arg = rawArgs[i];
|
|
570
|
+
if (valueFlags.has(arg)) {
|
|
571
|
+
i += 1;
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
if (arg.startsWith("--"))
|
|
575
|
+
continue;
|
|
576
|
+
positional.push(arg);
|
|
577
|
+
}
|
|
578
|
+
return positional;
|
|
579
|
+
}
|
|
552
580
|
function recordProvisionedEvent(ledger, event) {
|
|
553
581
|
if (event.service === "glitchtip")
|
|
554
582
|
ledger.record({ kind: "glitchtip", project: event.project });
|
|
@@ -631,15 +659,32 @@ async function handleAdd() {
|
|
|
631
659
|
.map((s) => s.trim().toLowerCase())
|
|
632
660
|
.every((s) => allServices.includes(s));
|
|
633
661
|
};
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
const
|
|
662
|
+
const nameFlag = flagValue("--name");
|
|
663
|
+
const domainFlag = flagValue("--domain");
|
|
664
|
+
const serverDirFlag = flagValue("--server-dir");
|
|
665
|
+
const clientDirFlag = flagValue("--client-dir");
|
|
666
|
+
const projectDirFlag = flagValue("--project-dir");
|
|
667
|
+
const surfaceFlag = flagValue("--surfaces");
|
|
668
|
+
const projectDirFromFlag = projectDirFlag ? resolve(projectDirFlag) : undefined;
|
|
669
|
+
if (projectDirFromFlag && !existsSync(projectDirFromFlag)) {
|
|
670
|
+
console.log(chalk.red(` --project-dir does not exist: ${projectDirFromFlag}`));
|
|
671
|
+
process.exit(1);
|
|
672
|
+
}
|
|
673
|
+
const positional = addPositionals(args.slice(1));
|
|
637
674
|
const firstArgIsService = isServiceExpr(positional[0]);
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
675
|
+
const positionalProjectName = firstArgIsService ? undefined : positional[0];
|
|
676
|
+
let inferredProjectDir = projectDirFromFlag ??
|
|
677
|
+
(positionalProjectName && existsSync(resolve(positionalProjectName))
|
|
678
|
+
? resolve(positionalProjectName)
|
|
679
|
+
: inferProjectDir(process.cwd()));
|
|
680
|
+
let inferredManifest = inferredProjectDir ? readManifest(inferredProjectDir) : null;
|
|
681
|
+
let baseName = positionalProjectName ?? nameFlag ?? inferredManifest?.name;
|
|
641
682
|
const rawService = firstArgIsService ? positional[0] : positional[1];
|
|
642
683
|
if (!baseName) {
|
|
684
|
+
if (!process.stdin.isTTY) {
|
|
685
|
+
console.log(chalk.red(" Project name is required. Pass <project-name> or --name <name>."));
|
|
686
|
+
process.exit(1);
|
|
687
|
+
}
|
|
643
688
|
const { input } = await import("@inquirer/prompts");
|
|
644
689
|
const { validateProjectName } = await import("./utils/validate.js");
|
|
645
690
|
baseName = await input({
|
|
@@ -647,14 +692,21 @@ async function handleAdd() {
|
|
|
647
692
|
validate: validateProjectName,
|
|
648
693
|
});
|
|
649
694
|
}
|
|
695
|
+
if (!inferredProjectDir) {
|
|
696
|
+
const namedProjectDir = resolve(baseName);
|
|
697
|
+
if (existsSync(namedProjectDir)) {
|
|
698
|
+
inferredProjectDir = namedProjectDir;
|
|
699
|
+
inferredManifest = readManifest(namedProjectDir);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
650
702
|
const alreadyAdded = servicesAlreadyAdded({
|
|
651
703
|
baseName,
|
|
652
704
|
projectDir: inferredProjectDir,
|
|
653
705
|
manifest: inferredManifest,
|
|
654
706
|
});
|
|
655
707
|
const impossible = servicesImpossibleForProject(inferredManifest);
|
|
656
|
-
const
|
|
657
|
-
const addableServices = allServices.filter((service) => !
|
|
708
|
+
const rerunnableServices = new Set(["search-console"]);
|
|
709
|
+
const addableServices = allServices.filter((service) => !alreadyAdded.has(service) && !impossible.has(service));
|
|
658
710
|
let services;
|
|
659
711
|
if (!rawService) {
|
|
660
712
|
if (addableServices.length === 0) {
|
|
@@ -704,13 +756,19 @@ async function handleAdd() {
|
|
|
704
756
|
console.log(chalk.dim(` Valid: ${allServices.join(", ")}, or 'all'`));
|
|
705
757
|
process.exit(1);
|
|
706
758
|
}
|
|
707
|
-
const skipped = requested.filter((service) =>
|
|
759
|
+
const skipped = requested.filter((service) => {
|
|
760
|
+
const svc = service;
|
|
761
|
+
return impossible.has(svc) || (alreadyAdded.has(svc) && !rerunnableServices.has(svc));
|
|
762
|
+
});
|
|
708
763
|
if (skipped.length > 0) {
|
|
709
764
|
console.log(chalk.red(` Refusing to add already-present/unavailable service(s): ${skipped.join(", ")}`));
|
|
710
765
|
console.log(chalk.dim(" Run `hatchkit remove` first if you want Hatchkit to recreate them."));
|
|
711
766
|
process.exit(1);
|
|
712
767
|
}
|
|
713
|
-
services = requested.filter((service) =>
|
|
768
|
+
services = requested.filter((service) => {
|
|
769
|
+
const svc = service;
|
|
770
|
+
return !impossible.has(svc) && (!alreadyAdded.has(svc) || rerunnableServices.has(svc));
|
|
771
|
+
});
|
|
714
772
|
if (services.length === 0) {
|
|
715
773
|
console.log(chalk.green(` Nothing to add — requested service(s) are already present or unavailable.`));
|
|
716
774
|
return;
|
|
@@ -722,22 +780,29 @@ async function handleAdd() {
|
|
|
722
780
|
// --surfaces=<shared|separate|server-only|client-only>
|
|
723
781
|
// --server-dir <path> → absolute or project-relative env dir for the server
|
|
724
782
|
// --client-dir <path> → same for the client
|
|
783
|
+
// --domain <domain> → site/domain-scoped services (Plausible/Search Console)
|
|
784
|
+
// --name <name> → project name when no positional/manifest name exists
|
|
725
785
|
// (no surface flags) → prompt interactively
|
|
726
786
|
const noWrite = args.includes("--no-write");
|
|
727
787
|
const enableDevObs = args.includes("--enable-dev-obs");
|
|
728
|
-
const surfaceFlag = args.find((a) => a.startsWith("--surfaces="))?.slice("--surfaces=".length);
|
|
729
|
-
const serverDirIdx = args.indexOf("--server-dir");
|
|
730
|
-
const clientDirIdx = args.indexOf("--client-dir");
|
|
731
|
-
const projectDirIdx = args.indexOf("--project-dir");
|
|
732
|
-
const serverDirFlag = serverDirIdx >= 0 ? args[serverDirIdx + 1] : undefined;
|
|
733
|
-
const clientDirFlag = clientDirIdx >= 0 ? args[clientDirIdx + 1] : undefined;
|
|
734
|
-
const projectDirFlag = projectDirIdx >= 0 ? args[projectDirIdx + 1] : undefined;
|
|
735
|
-
const { resolve: resolvePath } = await import("node:path");
|
|
736
788
|
const validSurfaceModes = ["shared", "separate", "server-only", "client-only"];
|
|
789
|
+
const noEnvServices = new Set(["email", "search-console"]);
|
|
790
|
+
const onlyNoEnvServices = services.every((service) => noEnvServices.has(service));
|
|
737
791
|
let surfaces = undefined;
|
|
738
792
|
if (noWrite) {
|
|
739
793
|
surfaces = false;
|
|
740
794
|
}
|
|
795
|
+
else if (onlyNoEnvServices) {
|
|
796
|
+
const projectDir = inferredProjectDir;
|
|
797
|
+
if (!projectDir) {
|
|
798
|
+
console.log(chalk.red(" A project directory is required for no-env services. Pass --project-dir <path>."));
|
|
799
|
+
process.exit(1);
|
|
800
|
+
}
|
|
801
|
+
surfaces = {
|
|
802
|
+
mode: provisionSurfaceModeFromManifest(inferredManifest),
|
|
803
|
+
projectDir,
|
|
804
|
+
};
|
|
805
|
+
}
|
|
741
806
|
else if (surfaceFlag || serverDirFlag || clientDirFlag || projectDirFlag) {
|
|
742
807
|
// Non-interactive surface config: require every field we need.
|
|
743
808
|
if (!surfaceFlag || !validSurfaceModes.includes(surfaceFlag)) {
|
|
@@ -757,16 +822,16 @@ async function handleAdd() {
|
|
|
757
822
|
}
|
|
758
823
|
surfaces = {
|
|
759
824
|
mode,
|
|
760
|
-
serverEnvDir: needsServer ?
|
|
761
|
-
clientEnvDir: needsClient ?
|
|
762
|
-
// --project-dir is optional in the flag path.
|
|
763
|
-
//
|
|
764
|
-
//
|
|
765
|
-
//
|
|
766
|
-
//
|
|
825
|
+
serverEnvDir: needsServer ? resolve(serverDirFlag) : undefined,
|
|
826
|
+
clientEnvDir: needsClient ? resolve(clientDirFlag) : undefined,
|
|
827
|
+
// --project-dir is optional in the flag path. It points at the
|
|
828
|
+
// project root used for manifest/package/CNAME inference (and for
|
|
829
|
+
// s3Buckets). When absent and the serverEnvDir is a
|
|
830
|
+
// `packages/server` style subdir, we infer it by walking up two
|
|
831
|
+
// segments.
|
|
767
832
|
projectDir: projectDirFlag
|
|
768
|
-
?
|
|
769
|
-
: inferProjectDir(needsServer ?
|
|
833
|
+
? resolve(projectDirFlag)
|
|
834
|
+
: inferProjectDir(needsServer ? resolve(serverDirFlag) : undefined),
|
|
770
835
|
};
|
|
771
836
|
}
|
|
772
837
|
const ledger = RunLedger.resumeOrStart(baseName);
|
|
@@ -775,6 +840,7 @@ async function handleAdd() {
|
|
|
775
840
|
services,
|
|
776
841
|
surfaces,
|
|
777
842
|
enableDevObs,
|
|
843
|
+
domain: domainFlag,
|
|
778
844
|
failIfExists: true,
|
|
779
845
|
onProvisioned: (event) => recordProvisionedEvent(ledger, event),
|
|
780
846
|
});
|
|
@@ -2354,6 +2420,7 @@ function printHelp(topic) {
|
|
|
2354
2420
|
|
|
2355
2421
|
${chalk.bold("Usage:")}
|
|
2356
2422
|
hatchkit add [<project-name>] [<services>] [flags]
|
|
2423
|
+
hatchkit add [<services>] --name <project-name> [flags]
|
|
2357
2424
|
hatchkit add [<services>] [flags] ${chalk.dim("(inside a project with .hatchkit.json)")}
|
|
2358
2425
|
|
|
2359
2426
|
${chalk.bold("What it does:")}
|
|
@@ -2407,14 +2474,21 @@ function printHelp(topic) {
|
|
|
2407
2474
|
--surfaces=<mode> shared | server-only | client-only | separate
|
|
2408
2475
|
--server-dir <path> Server env directory (skips prompt when set).
|
|
2409
2476
|
--client-dir <path> Client env directory (skips prompt when set).
|
|
2410
|
-
--project-dir <path> Project root
|
|
2477
|
+
--project-dir <path> Project root for manifest/package/CNAME inference
|
|
2478
|
+
(needed for s3 and non-Hatchkit Search Console onboarding;
|
|
2411
2479
|
inferred from --server-dir if omitted).
|
|
2480
|
+
--name <name> Project name when no positional or manifest name exists.
|
|
2481
|
+
--domain <domain> Site/domain-scoped services (Plausible, Search Console).
|
|
2412
2482
|
|
|
2413
2483
|
${chalk.bold("Examples:")}
|
|
2414
2484
|
hatchkit add
|
|
2415
2485
|
hatchkit add search-console
|
|
2416
2486
|
hatchkit add raptor-runner
|
|
2417
2487
|
hatchkit add raptor-runner all --enable-dev-obs
|
|
2488
|
+
hatchkit add search-console --name asteroids --domain asteroids.trebeljahr.com \\
|
|
2489
|
+
--project-dir /Users/rico/projects/asteroid-game
|
|
2490
|
+
hatchkit add my-app search-console --domain app.example.com --project-dir ./my-app
|
|
2491
|
+
hatchkit add fractal-garden search-console --domain fractal.garden
|
|
2418
2492
|
hatchkit add raptor-runner glitchtip,resend --no-write
|
|
2419
2493
|
hatchkit add raptor-runner all --surfaces=shared \\
|
|
2420
2494
|
--server-dir ./raptor-runner/packages/server \\
|