@happier-dev/stack 0.1.0-preview.17.1 → 0.1.0-preview.21.1
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/docs/server-flavors.md +6 -6
- package/node_modules/@happier-dev/cli-common/dist/index.d.ts +2 -0
- package/node_modules/@happier-dev/cli-common/dist/index.d.ts.map +1 -1
- package/node_modules/@happier-dev/cli-common/dist/index.js +2 -0
- package/node_modules/@happier-dev/cli-common/dist/index.js.map +1 -1
- package/node_modules/@happier-dev/cli-common/dist/providers/index.d.ts +51 -0
- package/node_modules/@happier-dev/cli-common/dist/providers/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/providers/index.js +129 -0
- package/node_modules/@happier-dev/cli-common/dist/providers/index.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/index.d.ts +5 -0
- package/node_modules/@happier-dev/cli-common/dist/service/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/index.js +5 -0
- package/node_modules/@happier-dev/cli-common/dist/service/index.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/launchd.d.ts +19 -0
- package/node_modules/@happier-dev/cli-common/dist/service/launchd.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/launchd.js +117 -0
- package/node_modules/@happier-dev/cli-common/dist/service/launchd.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/manager.d.ts +55 -0
- package/node_modules/@happier-dev/cli-common/dist/service/manager.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/manager.js +302 -0
- package/node_modules/@happier-dev/cli-common/dist/service/manager.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/systemd.d.ts +12 -0
- package/node_modules/@happier-dev/cli-common/dist/service/systemd.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/systemd.js +75 -0
- package/node_modules/@happier-dev/cli-common/dist/service/systemd.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/windows.d.ts +8 -0
- package/node_modules/@happier-dev/cli-common/dist/service/windows.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/service/windows.js +29 -0
- package/node_modules/@happier-dev/cli-common/dist/service/windows.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/package.json +11 -0
- package/node_modules/@happier-dev/release-runtime/dist/assets.d.ts +22 -0
- package/node_modules/@happier-dev/release-runtime/dist/assets.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/assets.js +44 -0
- package/node_modules/@happier-dev/release-runtime/dist/assets.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/checksums.d.ts +5 -0
- package/node_modules/@happier-dev/release-runtime/dist/checksums.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/checksums.js +21 -0
- package/node_modules/@happier-dev/release-runtime/dist/checksums.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/extractPlan.d.ts +14 -0
- package/node_modules/@happier-dev/release-runtime/dist/extractPlan.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/extractPlan.js +39 -0
- package/node_modules/@happier-dev/release-runtime/dist/extractPlan.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/github.d.ts +20 -0
- package/node_modules/@happier-dev/release-runtime/dist/github.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/github.js +60 -0
- package/node_modules/@happier-dev/release-runtime/dist/github.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/index.d.ts +7 -0
- package/node_modules/@happier-dev/release-runtime/dist/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/index.js +7 -0
- package/node_modules/@happier-dev/release-runtime/dist/index.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/minisign.d.ts +7 -0
- package/node_modules/@happier-dev/release-runtime/dist/minisign.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/minisign.js +92 -0
- package/node_modules/@happier-dev/release-runtime/dist/minisign.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.d.ts +26 -0
- package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.d.ts.map +1 -0
- package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.js +53 -0
- package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.js.map +1 -0
- package/node_modules/@happier-dev/release-runtime/package.json +38 -0
- package/package.json +4 -2
- package/scripts/auth.mjs +3 -2
- package/scripts/auth_copy_from_pglite_lock_in_use.integration.test.mjs +1 -0
- package/scripts/auth_copy_from_runCapture.integration.test.mjs +8 -1
- package/scripts/auth_login_guided_server_no_expo.test.mjs +2 -0
- package/scripts/build.mjs +3 -18
- package/scripts/bundleWorkspaceDeps.mjs +5 -1
- package/scripts/bundleWorkspaceDeps.test.mjs +42 -1
- package/scripts/mobile.mjs +30 -2
- package/scripts/mobile_dev_client.mjs +7 -32
- package/scripts/mobile_dev_client_help_smoke.test.mjs +24 -0
- package/scripts/mobile_prebuild_happyDir_defined.test.mjs +47 -0
- package/scripts/mobile_prebuild_sets_rct_metro_port.test.mjs +81 -0
- package/scripts/mobile_run_ios_passes_port.integration.test.mjs +103 -0
- package/scripts/mobile_run_ios_uses_long_port_flag.test.mjs +106 -0
- package/scripts/providers_cmd.mjs +262 -0
- package/scripts/release_binary_smoke.integration.test.mjs +45 -37
- package/scripts/remote_cmd.mjs +352 -0
- package/scripts/self_host_daemon.real.integration.test.mjs +296 -0
- package/scripts/self_host_launchd.real.integration.test.mjs +211 -0
- package/scripts/self_host_runtime.mjs +1829 -327
- package/scripts/self_host_runtime.test.mjs +523 -1
- package/scripts/self_host_schtasks.real.integration.test.mjs +217 -0
- package/scripts/self_host_service_e2e_harness.mjs +93 -0
- package/scripts/self_host_systemd.real.integration.test.mjs +8 -86
- package/scripts/service.mjs +156 -26
- package/scripts/stack/command_arguments.mjs +1 -0
- package/scripts/stack/help_text.mjs +3 -1
- package/scripts/stack.mjs +2 -1
- package/scripts/stack_daemon_cmd.integration.test.mjs +37 -0
- package/scripts/stack_happy_cmd.integration.test.mjs +36 -0
- package/scripts/stack_pr_help_cmd.test.mjs +38 -0
- package/scripts/stop.mjs +2 -3
- package/scripts/utils/auth/credentials_paths.mjs +9 -9
- package/scripts/utils/auth/credentials_paths.test.mjs +8 -0
- package/scripts/utils/auth/orchestrated_stack_auth_flow.mjs +64 -3
- package/scripts/utils/auth/stable_scope_id.mjs +1 -1
- package/scripts/utils/cli/cli_registry.mjs +21 -0
- package/scripts/utils/cli/progress.mjs +8 -1
- package/scripts/utils/cli/progress.test.mjs +43 -0
- package/scripts/utils/dev/expo_dev.buildEnv.test.mjs +17 -0
- package/scripts/utils/dev/expo_dev.mjs +35 -5
- package/scripts/utils/dev/expo_dev_restart_port_reservation.test.mjs +180 -1
- package/scripts/utils/dev/expo_dev_runtime_metadata.test.mjs +126 -0
- package/scripts/utils/dev/expo_dev_verbose_logs.test.mjs +9 -2
- package/scripts/utils/mobile/dev_client_install_invocation.mjs +68 -0
- package/scripts/utils/mobile/dev_client_install_invocation.test.mjs +27 -0
- package/scripts/utils/server/port.mjs +20 -2
- package/scripts/utils/service/service_manager.definition.test.mjs +66 -0
- package/scripts/utils/service/service_manager.mjs +96 -0
- package/scripts/utils/service/service_manager.plan.test.mjs +37 -0
- package/scripts/utils/service/service_manager.test.mjs +20 -0
- package/scripts/utils/service/systemd_service_unit.mjs +1 -0
- package/scripts/utils/service/systemd_service_unit.test.mjs +42 -0
- package/scripts/utils/service/windows_schtasks_wrapper.mjs +1 -0
- package/scripts/utils/service/windows_schtasks_wrapper.test.mjs +25 -0
- package/scripts/utils/ui/ui_export_env.mjs +29 -0
- package/scripts/utils/ui/ui_export_env.test.mjs +25 -0
- package/scripts/worktrees.mjs +3 -0
- package/scripts/worktrees_status_default_target.test.mjs +56 -0
package/docs/server-flavors.md
CHANGED
|
@@ -9,7 +9,7 @@ Both flavors use the **same server codebase** (the monorepo server package, typi
|
|
|
9
9
|
### `happier-server-light` (recommended default)
|
|
10
10
|
|
|
11
11
|
- **No Docker required**
|
|
12
|
-
- Uses **
|
|
12
|
+
- Uses **SQLite by default** (stack-local file), with optional embedded Postgres via PGlite
|
|
13
13
|
- Stores local public files under the stack directory
|
|
14
14
|
- Best choice for a stable “main” stack and quick local installs
|
|
15
15
|
|
|
@@ -18,6 +18,7 @@ Light stacks are isolated by default:
|
|
|
18
18
|
```
|
|
19
19
|
~/.happier/stacks/<stack>/server-light/files
|
|
20
20
|
~/.happier/stacks/<stack>/server-light/pglite
|
|
21
|
+
~/.happier/stacks/<stack>/server-light/happier-server-light.sqlite
|
|
21
22
|
```
|
|
22
23
|
|
|
23
24
|
Key env vars (stored in the stack env file):
|
|
@@ -65,10 +66,10 @@ For a “one URL” UX (especially with Tailscale), hstack starts a lightweight
|
|
|
65
66
|
|
|
66
67
|
This means `hstack start --server=happier-server` can still work end-to-end without requiring AWS S3 or a separate nginx setup.
|
|
67
68
|
|
|
68
|
-
## Migrating between flavors (
|
|
69
|
+
## Migrating between flavors (light ⇢ full)
|
|
69
70
|
|
|
70
71
|
hstack includes an **experimental** migration helper that can copy core chat data from a
|
|
71
|
-
`happier-server-light` stack
|
|
72
|
+
`happier-server-light` stack into a `happier-server` stack (Docker Postgres):
|
|
72
73
|
|
|
73
74
|
```bash
|
|
74
75
|
hstack migrate light-to-server --from-stack=main --to-stack=full1
|
|
@@ -90,7 +91,7 @@ Notes:
|
|
|
90
91
|
- **`hstack dev`** is for rapid iteration:
|
|
91
92
|
- for `happier-server`: hstack runs `prisma migrate deploy` by default (configurable via `HAPPIER_STACK_PRISMA_MIGRATE`).
|
|
92
93
|
- for `happier-server-light`:
|
|
93
|
-
- hstack runs the server package’s `migrate:light:deploy` script, which applies
|
|
94
|
+
- hstack runs the server package’s `migrate:light:deploy` script, which applies provider-specific light migrations (SQLite by default, or PGlite when configured).
|
|
94
95
|
|
|
95
96
|
Important: for a given run (`hstack start` / `hstack dev`) you choose **one** flavor.
|
|
96
97
|
|
|
@@ -143,5 +144,4 @@ There are two separate concepts:
|
|
|
143
144
|
|
|
144
145
|
## SQLite note
|
|
145
146
|
|
|
146
|
-
SQLite is
|
|
147
|
-
|
|
147
|
+
SQLite is the default DB for `happier-server-light`. You can opt into embedded Postgres (PGlite) by setting `HAPPIER_DB_PROVIDER=pglite` in the stack env.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * as update from './update/index.js';
|
|
2
2
|
export * as workspaces from './workspaces/index.js';
|
|
3
3
|
export * as links from './links.js';
|
|
4
|
+
export * as service from './service/index.js';
|
|
5
|
+
export * as providers from './providers/index.js';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * as update from './update/index.js';
|
|
2
2
|
export * as workspaces from './workspaces/index.js';
|
|
3
3
|
export * as links from './links.js';
|
|
4
|
+
export * as service from './service/index.js';
|
|
5
|
+
export * as providers from './providers/index.js';
|
|
4
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AgentId, ProviderCliInstallPlatform, ProviderCliInstallSpec } from '@happier-dev/agents';
|
|
2
|
+
export type ProviderCliInstallPlan = Readonly<{
|
|
3
|
+
providerId: AgentId;
|
|
4
|
+
title: string;
|
|
5
|
+
binaries: ReadonlyArray<string>;
|
|
6
|
+
platform: ProviderCliInstallPlatform;
|
|
7
|
+
docsUrl: string | null;
|
|
8
|
+
commands: ReadonlyArray<Readonly<{
|
|
9
|
+
cmd: string;
|
|
10
|
+
args: ReadonlyArray<string>;
|
|
11
|
+
requiresAdmin: boolean;
|
|
12
|
+
note: string | null;
|
|
13
|
+
}>>;
|
|
14
|
+
requiresAdmin: boolean;
|
|
15
|
+
}>;
|
|
16
|
+
export type ProviderCliInstallPlanResult = Readonly<{
|
|
17
|
+
ok: true;
|
|
18
|
+
plan: ProviderCliInstallPlan;
|
|
19
|
+
spec: ProviderCliInstallSpec;
|
|
20
|
+
}> | Readonly<{
|
|
21
|
+
ok: false;
|
|
22
|
+
errorCode: 'no-recipe';
|
|
23
|
+
errorMessage: string;
|
|
24
|
+
spec: ProviderCliInstallSpec;
|
|
25
|
+
}>;
|
|
26
|
+
export declare function resolvePlatformFromNodePlatform(nodePlatform: string): ProviderCliInstallPlatform | null;
|
|
27
|
+
export declare function planProviderCliInstall(params: Readonly<{
|
|
28
|
+
providerId: AgentId;
|
|
29
|
+
platform: ProviderCliInstallPlatform;
|
|
30
|
+
}>): ProviderCliInstallPlanResult;
|
|
31
|
+
export type InstallProviderCliResult = Readonly<{
|
|
32
|
+
ok: true;
|
|
33
|
+
plan: ProviderCliInstallPlan;
|
|
34
|
+
alreadyInstalled: boolean;
|
|
35
|
+
logPath: string | null;
|
|
36
|
+
}> | Readonly<{
|
|
37
|
+
ok: false;
|
|
38
|
+
errorCode: 'no-recipe' | 'command-not-found' | 'command-exec-failed' | 'command-failed';
|
|
39
|
+
errorMessage: string;
|
|
40
|
+
plan: ProviderCliInstallPlan | null;
|
|
41
|
+
logPath: string | null;
|
|
42
|
+
}>;
|
|
43
|
+
export declare function installProviderCli(params: Readonly<{
|
|
44
|
+
providerId: AgentId;
|
|
45
|
+
platform: ProviderCliInstallPlatform;
|
|
46
|
+
env?: NodeJS.ProcessEnv;
|
|
47
|
+
logDir?: string | null;
|
|
48
|
+
dryRun?: boolean;
|
|
49
|
+
skipIfInstalled?: boolean;
|
|
50
|
+
}>): InstallProviderCliResult;
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGvG,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,0BAA0B,CAAC;IACrC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAC;IAC7H,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GACpC,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC,GAClF,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC,CAAC;AAExG,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI,CAKvG;AA0BD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,0BAA0B,CAAA;CAAE,CAAC,GAAG,4BAA4B,CAqBpJ;AAwCD,MAAM,MAAM,wBAAwB,GAChC,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GACvG,QAAQ,CAAC;IACP,EAAE,EAAE,KAAK,CAAC;IACV,SAAS,EAAE,WAAW,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC,CAAC;AAEP,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClD,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,0BAA0B,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC,GAAG,wBAAwB,CAiD5B"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, writeFileSync, appendFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { getProviderCliInstallSpec } from '@happier-dev/agents';
|
|
6
|
+
export function resolvePlatformFromNodePlatform(nodePlatform) {
|
|
7
|
+
if (nodePlatform === 'darwin')
|
|
8
|
+
return 'darwin';
|
|
9
|
+
if (nodePlatform === 'linux')
|
|
10
|
+
return 'linux';
|
|
11
|
+
if (nodePlatform === 'win32')
|
|
12
|
+
return 'win32';
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function commandExists(cmd, env) {
|
|
16
|
+
const name = String(cmd ?? '').trim();
|
|
17
|
+
if (!name)
|
|
18
|
+
return false;
|
|
19
|
+
const pathEnv = env.PATH ?? process.env.PATH;
|
|
20
|
+
if (process.platform === 'win32') {
|
|
21
|
+
const res = spawnSync('where', [name], { stdio: 'ignore', env: { ...process.env, ...env, PATH: pathEnv } });
|
|
22
|
+
return (res.status ?? 1) === 0;
|
|
23
|
+
}
|
|
24
|
+
const res = spawnSync('sh', ['-lc', `command -v ${name} >/dev/null 2>&1`], { stdio: 'ignore', env: { ...process.env, ...env, PATH: pathEnv } });
|
|
25
|
+
return (res.status ?? 1) === 0;
|
|
26
|
+
}
|
|
27
|
+
function resolveProviderInstallCommands(spec, platform) {
|
|
28
|
+
const commandsRaw = spec.install?.[platform] ?? null;
|
|
29
|
+
if (!commandsRaw || commandsRaw.length === 0)
|
|
30
|
+
return null;
|
|
31
|
+
return commandsRaw.map((c) => ({
|
|
32
|
+
cmd: c.cmd,
|
|
33
|
+
args: [...c.args],
|
|
34
|
+
requiresAdmin: Boolean(c.requiresAdmin),
|
|
35
|
+
note: typeof c.note === 'string' ? c.note : null,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
export function planProviderCliInstall(params) {
|
|
39
|
+
const spec = getProviderCliInstallSpec(params.providerId);
|
|
40
|
+
const commands = resolveProviderInstallCommands(spec, params.platform);
|
|
41
|
+
if (!commands) {
|
|
42
|
+
return { ok: false, errorCode: 'no-recipe', spec, errorMessage: `No auto-install recipe available for ${spec.id} on ${params.platform}.` };
|
|
43
|
+
}
|
|
44
|
+
const requiresAdmin = commands.some((c) => c.requiresAdmin);
|
|
45
|
+
return {
|
|
46
|
+
ok: true,
|
|
47
|
+
spec,
|
|
48
|
+
plan: {
|
|
49
|
+
providerId: spec.id,
|
|
50
|
+
title: spec.title,
|
|
51
|
+
binaries: spec.binaries,
|
|
52
|
+
platform: params.platform,
|
|
53
|
+
docsUrl: typeof spec.docsUrl === 'string' ? spec.docsUrl : null,
|
|
54
|
+
commands,
|
|
55
|
+
requiresAdmin,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function resolveLogPath(params) {
|
|
60
|
+
const base = typeof params.logDir === 'string' && params.logDir.trim() ? params.logDir.trim() : join(tmpdir(), 'happier-provider-installs');
|
|
61
|
+
mkdirSync(base, { recursive: true });
|
|
62
|
+
return join(base, `install-provider-${params.providerId}-${Date.now()}.log`);
|
|
63
|
+
}
|
|
64
|
+
function writeLogHeader(logPath, plan) {
|
|
65
|
+
writeFileSync(logPath, [
|
|
66
|
+
`# providerId: ${plan.providerId}`,
|
|
67
|
+
`# platform: ${plan.platform}`,
|
|
68
|
+
`# requiresAdmin: ${plan.requiresAdmin ? '1' : '0'}`,
|
|
69
|
+
'',
|
|
70
|
+
].join('\n'), 'utf8');
|
|
71
|
+
}
|
|
72
|
+
function appendCommandLog(logPath, cmd, args, stdout, stderr, status) {
|
|
73
|
+
appendFileSync(logPath, [
|
|
74
|
+
'',
|
|
75
|
+
`## ${cmd} ${args.join(' ')}`.trim(),
|
|
76
|
+
`# exit: ${status ?? 'null'}`,
|
|
77
|
+
'',
|
|
78
|
+
'### stdout',
|
|
79
|
+
stdout || '',
|
|
80
|
+
'',
|
|
81
|
+
'### stderr',
|
|
82
|
+
stderr || '',
|
|
83
|
+
'',
|
|
84
|
+
].join('\n'), 'utf8');
|
|
85
|
+
}
|
|
86
|
+
export function installProviderCli(params) {
|
|
87
|
+
const env = params.env ?? process.env;
|
|
88
|
+
const skipIfInstalled = params.skipIfInstalled !== false;
|
|
89
|
+
const planned = planProviderCliInstall({ providerId: params.providerId, platform: params.platform });
|
|
90
|
+
if (!planned.ok) {
|
|
91
|
+
return { ok: false, errorCode: planned.errorCode, errorMessage: planned.errorMessage, plan: null, logPath: null };
|
|
92
|
+
}
|
|
93
|
+
const plan = planned.plan;
|
|
94
|
+
if (skipIfInstalled) {
|
|
95
|
+
const allPresent = plan.binaries.every((b) => commandExists(b, env));
|
|
96
|
+
if (allPresent) {
|
|
97
|
+
return { ok: true, plan, alreadyInstalled: true, logPath: null };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (params.dryRun) {
|
|
101
|
+
return { ok: true, plan, alreadyInstalled: false, logPath: null };
|
|
102
|
+
}
|
|
103
|
+
const logPath = resolveLogPath({ providerId: params.providerId, logDir: params.logDir });
|
|
104
|
+
writeLogHeader(logPath, plan);
|
|
105
|
+
for (const c of plan.commands) {
|
|
106
|
+
if (!commandExists(c.cmd, env)) {
|
|
107
|
+
return { ok: false, errorCode: 'command-not-found', errorMessage: `Command not found: ${c.cmd}`, plan, logPath };
|
|
108
|
+
}
|
|
109
|
+
const res = spawnSync(c.cmd, [...c.args], { encoding: 'utf8', env: { ...process.env, ...env } });
|
|
110
|
+
if (res.error) {
|
|
111
|
+
appendCommandLog(logPath, c.cmd, c.args, '', res.error.message, res.status ?? null);
|
|
112
|
+
return { ok: false, errorCode: 'command-exec-failed', errorMessage: res.error.message, plan, logPath };
|
|
113
|
+
}
|
|
114
|
+
const status = typeof res.status === 'number' ? res.status : null;
|
|
115
|
+
appendCommandLog(logPath, c.cmd, c.args, String(res.stdout ?? ''), String(res.stderr ?? ''), status);
|
|
116
|
+
if (status !== 0) {
|
|
117
|
+
const stderr = String(res.stderr ?? '').trim();
|
|
118
|
+
return {
|
|
119
|
+
ok: false,
|
|
120
|
+
errorCode: 'command-failed',
|
|
121
|
+
errorMessage: stderr || `Command failed (${status ?? 'unknown'}): ${c.cmd}`,
|
|
122
|
+
plan,
|
|
123
|
+
logPath,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { ok: true, plan, alreadyInstalled: false, logPath };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/service/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/service/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function buildLaunchdPath(params?: Readonly<{
|
|
2
|
+
execPath?: string;
|
|
3
|
+
basePath?: string;
|
|
4
|
+
}>): string;
|
|
5
|
+
export declare function buildLaunchdPlistXml(params: Readonly<{
|
|
6
|
+
label: string;
|
|
7
|
+
programArgs: readonly string[];
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
stdoutPath: string;
|
|
10
|
+
stderrPath: string;
|
|
11
|
+
workingDirectory?: string;
|
|
12
|
+
keepAliveOnFailure?: boolean;
|
|
13
|
+
startIntervalSec?: number;
|
|
14
|
+
startCalendarInterval?: Readonly<{
|
|
15
|
+
hour: number;
|
|
16
|
+
minute: number;
|
|
17
|
+
}>;
|
|
18
|
+
}>): string;
|
|
19
|
+
//# sourceMappingURL=launchd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd.d.ts","sourceRoot":"","sources":["../../src/service/launchd.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,GAAG,MAAM,CAmBxG;AAWD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC,GAAG,MAAM,CA0FV"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { dirname } from 'node:path';
|
|
2
|
+
function splitPath(p) {
|
|
3
|
+
return String(p ?? '')
|
|
4
|
+
.split(':')
|
|
5
|
+
.map((s) => s.trim())
|
|
6
|
+
.filter(Boolean);
|
|
7
|
+
}
|
|
8
|
+
export function buildLaunchdPath(params = {}) {
|
|
9
|
+
// launchd starts with a minimal environment; ensure common tool paths exist,
|
|
10
|
+
// and include the current Node binary directory so shell shims that exec `node`
|
|
11
|
+
// still work (e.g. nvm-managed installs).
|
|
12
|
+
const execPath = String(params.execPath ?? '').trim();
|
|
13
|
+
const basePath = String(params.basePath ?? '').trim();
|
|
14
|
+
const nodeDir = execPath ? dirname(execPath) : '';
|
|
15
|
+
const defaults = splitPath('/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin');
|
|
16
|
+
const fromNode = nodeDir ? [nodeDir] : [];
|
|
17
|
+
const fromEnv = splitPath(basePath);
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
const out = [];
|
|
20
|
+
for (const part of [...fromNode, ...fromEnv, ...defaults]) {
|
|
21
|
+
if (seen.has(part))
|
|
22
|
+
continue;
|
|
23
|
+
seen.add(part);
|
|
24
|
+
out.push(part);
|
|
25
|
+
}
|
|
26
|
+
return out.join(':') || '/usr/bin:/bin:/usr/sbin:/sbin';
|
|
27
|
+
}
|
|
28
|
+
function xmlEscape(s) {
|
|
29
|
+
return String(s ?? '')
|
|
30
|
+
.replaceAll('&', '&')
|
|
31
|
+
.replaceAll('<', '<')
|
|
32
|
+
.replaceAll('>', '>')
|
|
33
|
+
.replaceAll('"', '"')
|
|
34
|
+
.replaceAll("'", ''');
|
|
35
|
+
}
|
|
36
|
+
export function buildLaunchdPlistXml(params) {
|
|
37
|
+
const label = String(params.label ?? '').trim();
|
|
38
|
+
if (!label)
|
|
39
|
+
throw new Error('label is required');
|
|
40
|
+
const programArgs = Array.isArray(params.programArgs)
|
|
41
|
+
? params.programArgs.map((a) => String(a ?? '')).filter(Boolean)
|
|
42
|
+
: [];
|
|
43
|
+
if (programArgs.length === 0)
|
|
44
|
+
throw new Error('programArgs is required');
|
|
45
|
+
const envEntries = Object.entries(params.env ?? {}).filter(([k]) => String(k).trim());
|
|
46
|
+
const programArgsXml = programArgs.map((a) => ` <string>${xmlEscape(a)}</string>`).join('\n');
|
|
47
|
+
const envXml = envEntries
|
|
48
|
+
.map(([k, v]) => ` <key>${xmlEscape(k)}</key>\n <string>${xmlEscape(String(v ?? ''))}</string>`)
|
|
49
|
+
.join('\n');
|
|
50
|
+
const stdoutPath = String(params.stdoutPath ?? '').trim();
|
|
51
|
+
const stderrPath = String(params.stderrPath ?? '').trim();
|
|
52
|
+
const workingDirectory = String(params.workingDirectory ?? '').trim();
|
|
53
|
+
const workingDirXml = workingDirectory
|
|
54
|
+
? `\n <key>WorkingDirectory</key>\n <string>${xmlEscape(workingDirectory)}</string>\n`
|
|
55
|
+
: '\n';
|
|
56
|
+
const keepAlive = params.keepAliveOnFailure === false
|
|
57
|
+
? ''
|
|
58
|
+
: (`\n <key>KeepAlive</key>\n` +
|
|
59
|
+
` <dict>\n` +
|
|
60
|
+
` <key>SuccessfulExit</key>\n` +
|
|
61
|
+
` <false/>\n` +
|
|
62
|
+
` </dict>\n`);
|
|
63
|
+
const intervalRaw = Number(params.startIntervalSec);
|
|
64
|
+
const interval = Number.isFinite(intervalRaw) && intervalRaw > 0 ? Math.floor(intervalRaw) : 0;
|
|
65
|
+
const startInterval = interval
|
|
66
|
+
? `\n <key>StartInterval</key>\n <integer>${interval}</integer>\n`
|
|
67
|
+
: '';
|
|
68
|
+
const calendar = params.startCalendarInterval;
|
|
69
|
+
const calHourRaw = Number(calendar?.hour);
|
|
70
|
+
const calMinuteRaw = Number(calendar?.minute);
|
|
71
|
+
const calHour = Number.isFinite(calHourRaw) ? Math.floor(calHourRaw) : NaN;
|
|
72
|
+
const calMinute = Number.isFinite(calMinuteRaw) ? Math.floor(calMinuteRaw) : NaN;
|
|
73
|
+
const hasCalendar = Number.isFinite(calHour)
|
|
74
|
+
&& Number.isFinite(calMinute)
|
|
75
|
+
&& calHour >= 0
|
|
76
|
+
&& calHour <= 23
|
|
77
|
+
&& calMinute >= 0
|
|
78
|
+
&& calMinute <= 59;
|
|
79
|
+
const startCalendarInterval = hasCalendar
|
|
80
|
+
? (`\n <key>StartCalendarInterval</key>\n` +
|
|
81
|
+
` <dict>\n` +
|
|
82
|
+
` <key>Hour</key>\n` +
|
|
83
|
+
` <integer>${calHour}</integer>\n` +
|
|
84
|
+
` <key>Minute</key>\n` +
|
|
85
|
+
` <integer>${calMinute}</integer>\n` +
|
|
86
|
+
` </dict>\n`)
|
|
87
|
+
: '';
|
|
88
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
89
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
90
|
+
<plist version="1.0">
|
|
91
|
+
<dict>
|
|
92
|
+
<key>Label</key>
|
|
93
|
+
<string>${xmlEscape(label)}</string>
|
|
94
|
+
|
|
95
|
+
<key>ProgramArguments</key>
|
|
96
|
+
<array>
|
|
97
|
+
${programArgsXml}
|
|
98
|
+
</array>
|
|
99
|
+
|
|
100
|
+
<key>RunAtLoad</key>
|
|
101
|
+
<true/>
|
|
102
|
+
${keepAlive}
|
|
103
|
+
${startCalendarInterval || startInterval}
|
|
104
|
+
${workingDirXml} <key>StandardOutPath</key>
|
|
105
|
+
<string>${xmlEscape(stdoutPath)}</string>
|
|
106
|
+
<key>StandardErrorPath</key>
|
|
107
|
+
<string>${xmlEscape(stderrPath)}</string>
|
|
108
|
+
|
|
109
|
+
<key>EnvironmentVariables</key>
|
|
110
|
+
<dict>
|
|
111
|
+
${envXml}
|
|
112
|
+
</dict>
|
|
113
|
+
</dict>
|
|
114
|
+
</plist>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=launchd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd.js","sourceRoot":"","sources":["../../src/service/launchd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAA6D,EAAE;IAC9F,6EAA6E;IAC7E,gFAAgF;IAChF,0CAA0C;IAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,SAAS,CAAC,gEAAgE,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;QAC1D,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,+BAA+B,CAAC;AAC1D,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;SACnB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAUnC;IACA,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAEjD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;QACnD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAChE,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtF,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnG,MAAM,MAAM,GAAG,UAAU;SACtB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,SAAS,CAAC,CAAC,CAAC,yBAAyB,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC;SACzG,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAEtE,MAAM,aAAa,GAAG,gBAAgB;QACpC,CAAC,CAAC,kDAAkD,SAAS,CAAC,gBAAgB,CAAC,aAAa;QAC5F,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,SAAS,GAAG,MAAM,CAAC,kBAAkB,KAAK,KAAK;QACnD,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CACE,8BAA8B;YAC9B,cAAc;YACd,mCAAmC;YACnC,kBAAkB;YAClB,eAAe,CAChB,CAAC;IAEN,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,aAAa,GAAG,QAAQ;QAC5B,CAAC,CAAC,gDAAgD,QAAQ,cAAc;QACxE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,QAAQ,GAAG,MAAM,CAAC,qBAAqB,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjF,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;WACvC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;WAC1B,OAAO,IAAI,CAAC;WACZ,OAAO,IAAI,EAAE;WACb,SAAS,IAAI,CAAC;WACd,SAAS,IAAI,EAAE,CAAC;IACrB,MAAM,qBAAqB,GAAG,WAAW;QACvC,CAAC,CAAC,CACE,0CAA0C;YAC1C,cAAc;YACd,yBAAyB;YACzB,kBAAkB,OAAO,cAAc;YACvC,2BAA2B;YAC3B,kBAAkB,SAAS,cAAc;YACzC,eAAe,CAChB;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;cAKK,SAAS,CAAC,KAAK,CAAC;;;;EAI5B,cAAc;;;;;EAKd,SAAS;EACT,qBAAqB,IAAI,aAAa;EACtC,aAAa;cACD,SAAS,CAAC,UAAU,CAAC;;cAErB,SAAS,CAAC,UAAU,CAAC;;;;EAIjC,MAAM;;;;CAIP,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type ServiceMode = 'user' | 'system';
|
|
2
|
+
export type ServiceBackend = 'systemd-user' | 'systemd-system' | 'launchd-user' | 'launchd-system' | 'schtasks-user' | 'schtasks-system';
|
|
3
|
+
export type ServiceSpec = Readonly<{
|
|
4
|
+
label: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
programArgs: readonly string[];
|
|
7
|
+
workingDirectory?: string;
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
runAsUser?: string;
|
|
10
|
+
stdoutPath?: string;
|
|
11
|
+
stderrPath?: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type ServiceDefinition = Readonly<{
|
|
14
|
+
kind: 'systemd-service' | 'launchd-plist' | 'windows-wrapper-ps1';
|
|
15
|
+
path: string;
|
|
16
|
+
contents: string;
|
|
17
|
+
mode: number;
|
|
18
|
+
}>;
|
|
19
|
+
export type PlannedWrite = Readonly<{
|
|
20
|
+
path: string;
|
|
21
|
+
contents: string;
|
|
22
|
+
mode?: number;
|
|
23
|
+
}>;
|
|
24
|
+
export type PlannedCommand = Readonly<{
|
|
25
|
+
cmd: string;
|
|
26
|
+
args: readonly string[];
|
|
27
|
+
allowFail?: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
export type ServicePlan = Readonly<{
|
|
30
|
+
writes: PlannedWrite[];
|
|
31
|
+
commands: PlannedCommand[];
|
|
32
|
+
}>;
|
|
33
|
+
export declare function resolveServiceBackend(params?: Readonly<{
|
|
34
|
+
platform?: NodeJS.Platform;
|
|
35
|
+
mode?: ServiceMode;
|
|
36
|
+
}>): ServiceBackend;
|
|
37
|
+
export declare function buildServiceDefinition(params: Readonly<{
|
|
38
|
+
backend: ServiceBackend;
|
|
39
|
+
homeDir: string;
|
|
40
|
+
spec: ServiceSpec;
|
|
41
|
+
}>): ServiceDefinition;
|
|
42
|
+
export declare function planServiceAction(params: Readonly<{
|
|
43
|
+
backend: ServiceBackend;
|
|
44
|
+
action: 'install' | 'uninstall' | 'start' | 'stop' | 'restart';
|
|
45
|
+
label: string;
|
|
46
|
+
definitionPath?: string;
|
|
47
|
+
definitionContents?: string;
|
|
48
|
+
taskName?: string;
|
|
49
|
+
persistent?: boolean;
|
|
50
|
+
uid?: number | null;
|
|
51
|
+
}>): ServicePlan;
|
|
52
|
+
export declare function applyServicePlan(plan: ServicePlan, options?: Readonly<{
|
|
53
|
+
runCommands?: boolean;
|
|
54
|
+
}>): Promise<void>;
|
|
55
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/service/manager.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,iBAAiB,CAAC;AAEtB,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,iBAAiB,GAAG,eAAe,GAAG,qBAAqB,CAAC;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACvF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACrG,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAAC;AAE3F,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAAE,CAAM,GAAG,cAAc,CAQ/H;AAwCD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,GAAG,iBAAiB,CAsD3I;AAQD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC;IACjD,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC,GAAG,WAAW,CAyIf;AAaD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,GAAE,QAAQ,CAAC;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB1H"}
|