paratix 0.3.0 → 0.4.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/README.md CHANGED
@@ -18,6 +18,7 @@ The result is a practical server automation tool with a compact mental model: mo
18
18
  - **TypeScript authoring**: use regular `.ts` files with imports, conditions, and editor tooling.
19
19
  - **Resilient SSH flow**: reconnects after reboots and SSH port changes when modules require it.
20
20
  - **Structured orchestration**: recipes and signals keep service reloads and grouped changes explicit.
21
+ - **Declarative host guards**: gate modules on package, command, file, directory, symlink, or socket state without embedding shell checks in strings.
21
22
  - **Strong bootstrap story**: supports explicit first-run flows and strict host-key handling.
22
23
  - **Practical built-in modules**: packages, files, services, users, SSH, firewall, systemd, sysctl, mount, rsync, and more.
23
24
 
@@ -93,6 +94,10 @@ Recipes group related modules into a named unit. They help structure larger play
93
94
 
94
95
  Signals are deferred side effects such as `service.reload(...)` or `service.restart(...)`. They run when the surrounding scope actually changed, and can also be flushed explicitly with `signals.flush()` when you need a checkpoint inside a larger flow.
95
96
 
97
+ ### Guards
98
+
99
+ Paratix also supports declarative host-state guards. Use `when.packageInstalled(...)`, `when.commandExists(...)`, `when.fileExists(...)`, `when.pathExists(...)`, `when.symlinkExists(...)`, or `when.socketExists(...)` and their inverted forms to gate modules or recipes on remote host state without shell-heavy playbooks.
100
+
96
101
  ## CLI
97
102
 
98
103
  ```text
@@ -4729,6 +4729,37 @@ var systemd = {
4729
4729
  // src/modules/ufw.ts
4730
4730
  var UFW = "ufw";
4731
4731
  var ufw = {
4732
+ /**
4733
+ * Ensure UFW is inactive. If UFW is not installed, this is treated as already satisfied.
4734
+ *
4735
+ * @returns A Module that ensures UFW is disabled.
4736
+ */
4737
+ disabled() {
4738
+ return {
4739
+ async apply(ssh2) {
4740
+ if (!ssh2) return failed("[ufw.disabled] SSH connection is required");
4741
+ const pm = await detectPackageManager(ssh2);
4742
+ if (pm == null || !await isPackageInstalled(ssh2, pm, UFW)) {
4743
+ return { status: "ok" };
4744
+ }
4745
+ const result = await ssh2.exec(`${UFW} --force disable`, {
4746
+ ignoreExitCode: true,
4747
+ silent: true
4748
+ });
4749
+ return result.code === 0 ? { status: "changed" } : failedCommand("[ufw.disabled] ufw disable failed", result);
4750
+ },
4751
+ async check(ssh2) {
4752
+ if (!ssh2) return NEEDS_APPLY;
4753
+ const pm = await detectPackageManager(ssh2);
4754
+ if (pm == null || !await isPackageInstalled(ssh2, pm, UFW)) {
4755
+ return "ok";
4756
+ }
4757
+ const status = await ssh2.output(`${UFW} status`);
4758
+ return status.includes("Status: inactive") ? "ok" : NEEDS_APPLY;
4759
+ },
4760
+ name: "ufw.disabled"
4761
+ };
4762
+ },
4732
4763
  /**
4733
4764
  * Ensure UFW is active. Enables the firewall non-interactively if not already running.
4734
4765
  *
@@ -4932,6 +4963,9 @@ export {
4932
4963
  failed,
4933
4964
  failedCommand,
4934
4965
  NEEDS_APPLY,
4966
+ detectPackageManager,
4967
+ isPackageInstalled,
4968
+ pkg,
4935
4969
  apt,
4936
4970
  archive,
4937
4971
  command,
@@ -4945,7 +4979,6 @@ export {
4945
4979
  mount,
4946
4980
  net,
4947
4981
  op,
4948
- pkg,
4949
4982
  releaseUpgrade,
4950
4983
  rsync,
4951
4984
  script,
@@ -4958,4 +4991,4 @@ export {
4958
4991
  ufw,
4959
4992
  user
4960
4993
  };
4961
- //# sourceMappingURL=chunk-ULJMW23T.js.map
4994
+ //# sourceMappingURL=chunk-C45YPXCX.js.map