@adecore/service 0.21.1 → 0.22.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
@@ -1,6 +1,6 @@
1
1
  # @adecore/service
2
2
 
3
- Definitions and injectable managers for macOS launchd GUI jobs and Linux systemd user services. The host supplies identity, paths, environment, commands and files. It keeps installation authorization and executable policy.
3
+ Definitions and managers for macOS launchd GUI jobs and Linux systemd user services, with everything they touch injected. The host supplies the identity, paths, environment, commands and files. Deciding who may install a service and which executable it runs stays with the host.
4
4
 
5
5
  ```sh
6
6
  bun add @adecore/service
@@ -23,8 +23,8 @@ const spec: ServiceSpec = {
23
23
  const definition = systemdUnit(spec);
24
24
  ```
25
25
 
26
- `/definitions` has no Node or Bun runtime imports. The root, `/manager`, `/platform` and `/system` are backend entrypoints. Importing them does not install or start a service.
26
+ `/definitions` imports nothing from Node or Bun. The root, `/manager`, `/platform` and `/system` are for a backend, and importing them installs or starts nothing.
27
27
 
28
- `install()` returns whether an existing definition changed, so a first install returns `false`. Await `restart()` for a changed definition, otherwise call `start()`. Uninstall does not stop a running job. Managers supply no authorization, lock, cancellation or automatic lingering.
28
+ `install()` returns whether an existing definition changed, so a first install returns `false`. Await `restart()` after a change, and call `start()` otherwise. Uninstalling does not stop a running job. The managers bring no authorization, lock, cancellation or automatic lingering.
29
29
 
30
- The full documentation covers the [overview](https://adecore.dev/service/), [definitions](https://adecore.dev/service/definitions) and [managers](https://adecore.dev/service/managers), with a test that uses fakes instead of real service commands.
30
+ The documentation has an [overview](https://adecore.dev/service/), [definitions](https://adecore.dev/service/definitions) and [managers](https://adecore.dev/service/managers), including a test that runs on fakes instead of the real service commands.
package/dist/manager.js CHANGED
@@ -1,10 +1,7 @@
1
1
  import { dirname, join } from 'node:path';
2
- function describe(result, what) {
3
- return `${what} failed (${result.code}): ${(result.stderr || result.stdout).trim() || 'no output'}`;
4
- }
5
2
  function expectSuccess(result, what) {
6
3
  if (result.code !== 0) {
7
- throw new Error(describe(result, what));
4
+ throw new Error(`${what} failed (${result.code}): ${(result.stderr || result.stdout).trim() || 'no output'}`);
8
5
  }
9
6
  }
10
7
  /*
@@ -13,10 +10,9 @@ function expectSuccess(result, what) {
13
10
  * the bundle, where the login shell's PATH and a log path in the home cannot be written.
14
11
  */
15
12
  export function launchdManager(options) {
16
- const label = options.label;
17
- const path = join(options.home, 'Library', 'LaunchAgents', `${label}.plist`);
13
+ const path = join(options.home, 'Library', 'LaunchAgents', `${options.label}.plist`);
18
14
  const domain = `gui/${options.uid}`;
19
- const target = `${domain}/${label}`;
15
+ const target = `${domain}/${options.label}`;
20
16
  const launchctl = (...args) => options.run('/bin/launchctl', args);
21
17
  const isLoaded = () => launchctl('print', target).code === 0;
22
18
  const bootstrap = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/service",
3
- "version": "0.21.1",
3
+ "version": "0.22.0",
4
4
  "description": "User service definitions and injectable launchd and systemd managers.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
package/src/manager.ts CHANGED
@@ -19,7 +19,7 @@ export interface ServiceFiles {
19
19
 
20
20
  export interface ServiceManager {
21
21
  readonly kind: 'launchd' | 'systemd';
22
- /* Where the definition lives, for the documentation and the error a person reads. */
22
+ /* The definition's file. */
23
23
  readonly path: string;
24
24
  isInstalled(): boolean;
25
25
  /* The definition on disk, null when there is none. */
@@ -41,13 +41,9 @@ export interface ServiceManager {
41
41
  linger?: { enabled(): boolean; enable(): void };
42
42
  }
43
43
 
44
- function describe(result: CommandResult, what: string): string {
45
- return `${what} failed (${result.code}): ${(result.stderr || result.stdout).trim() || 'no output'}`;
46
- }
47
-
48
44
  function expectSuccess(result: CommandResult, what: string): void {
49
45
  if (result.code !== 0) {
50
- throw new Error(describe(result, what));
46
+ throw new Error(`${what} failed (${result.code}): ${(result.stderr || result.stdout).trim() || 'no output'}`);
51
47
  }
52
48
  }
53
49
 
@@ -67,10 +63,9 @@ export interface LaunchdOptions {
67
63
  * the bundle, where the login shell's PATH and a log path in the home cannot be written.
68
64
  */
69
65
  export function launchdManager(options: LaunchdOptions): ServiceManager {
70
- const label = options.label;
71
- const path = join(options.home, 'Library', 'LaunchAgents', `${label}.plist`);
66
+ const path = join(options.home, 'Library', 'LaunchAgents', `${options.label}.plist`);
72
67
  const domain = `gui/${options.uid}`;
73
- const target = `${domain}/${label}`;
68
+ const target = `${domain}/${options.label}`;
74
69
  const launchctl = (...args: string[]): CommandResult => options.run('/bin/launchctl', args);
75
70
  const isLoaded = (): boolean => launchctl('print', target).code === 0;
76
71