@happier-dev/stack 0.1.0-preview.100.1 → 0.1.0-preview.138.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.
Files changed (109) hide show
  1. package/docs/server-flavors.md +6 -6
  2. package/node_modules/@happier-dev/cli-common/dist/index.d.ts +2 -0
  3. package/node_modules/@happier-dev/cli-common/dist/index.d.ts.map +1 -1
  4. package/node_modules/@happier-dev/cli-common/dist/index.js +2 -0
  5. package/node_modules/@happier-dev/cli-common/dist/index.js.map +1 -1
  6. package/node_modules/@happier-dev/cli-common/dist/providers/index.d.ts +51 -0
  7. package/node_modules/@happier-dev/cli-common/dist/providers/index.d.ts.map +1 -0
  8. package/node_modules/@happier-dev/cli-common/dist/providers/index.js +129 -0
  9. package/node_modules/@happier-dev/cli-common/dist/providers/index.js.map +1 -0
  10. package/node_modules/@happier-dev/cli-common/dist/service/index.d.ts +5 -0
  11. package/node_modules/@happier-dev/cli-common/dist/service/index.d.ts.map +1 -0
  12. package/node_modules/@happier-dev/cli-common/dist/service/index.js +5 -0
  13. package/node_modules/@happier-dev/cli-common/dist/service/index.js.map +1 -0
  14. package/node_modules/@happier-dev/cli-common/dist/service/launchd.d.ts +15 -0
  15. package/node_modules/@happier-dev/cli-common/dist/service/launchd.d.ts.map +1 -0
  16. package/node_modules/@happier-dev/cli-common/dist/service/launchd.js +97 -0
  17. package/node_modules/@happier-dev/cli-common/dist/service/launchd.js.map +1 -0
  18. package/node_modules/@happier-dev/cli-common/dist/service/manager.d.ts +55 -0
  19. package/node_modules/@happier-dev/cli-common/dist/service/manager.d.ts.map +1 -0
  20. package/node_modules/@happier-dev/cli-common/dist/service/manager.js +302 -0
  21. package/node_modules/@happier-dev/cli-common/dist/service/manager.js.map +1 -0
  22. package/node_modules/@happier-dev/cli-common/dist/service/systemd.d.ts +12 -0
  23. package/node_modules/@happier-dev/cli-common/dist/service/systemd.d.ts.map +1 -0
  24. package/node_modules/@happier-dev/cli-common/dist/service/systemd.js +75 -0
  25. package/node_modules/@happier-dev/cli-common/dist/service/systemd.js.map +1 -0
  26. package/node_modules/@happier-dev/cli-common/dist/service/windows.d.ts +8 -0
  27. package/node_modules/@happier-dev/cli-common/dist/service/windows.d.ts.map +1 -0
  28. package/node_modules/@happier-dev/cli-common/dist/service/windows.js +29 -0
  29. package/node_modules/@happier-dev/cli-common/dist/service/windows.js.map +1 -0
  30. package/node_modules/@happier-dev/cli-common/package.json +11 -0
  31. package/node_modules/@happier-dev/release-runtime/dist/assets.d.ts +22 -0
  32. package/node_modules/@happier-dev/release-runtime/dist/assets.d.ts.map +1 -0
  33. package/node_modules/@happier-dev/release-runtime/dist/assets.js +44 -0
  34. package/node_modules/@happier-dev/release-runtime/dist/assets.js.map +1 -0
  35. package/node_modules/@happier-dev/release-runtime/dist/checksums.d.ts +5 -0
  36. package/node_modules/@happier-dev/release-runtime/dist/checksums.d.ts.map +1 -0
  37. package/node_modules/@happier-dev/release-runtime/dist/checksums.js +21 -0
  38. package/node_modules/@happier-dev/release-runtime/dist/checksums.js.map +1 -0
  39. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.d.ts +14 -0
  40. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.d.ts.map +1 -0
  41. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.js +39 -0
  42. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.js.map +1 -0
  43. package/node_modules/@happier-dev/release-runtime/dist/github.d.ts +20 -0
  44. package/node_modules/@happier-dev/release-runtime/dist/github.d.ts.map +1 -0
  45. package/node_modules/@happier-dev/release-runtime/dist/github.js +60 -0
  46. package/node_modules/@happier-dev/release-runtime/dist/github.js.map +1 -0
  47. package/node_modules/@happier-dev/release-runtime/dist/index.d.ts +7 -0
  48. package/node_modules/@happier-dev/release-runtime/dist/index.d.ts.map +1 -0
  49. package/node_modules/@happier-dev/release-runtime/dist/index.js +7 -0
  50. package/node_modules/@happier-dev/release-runtime/dist/index.js.map +1 -0
  51. package/node_modules/@happier-dev/release-runtime/dist/minisign.d.ts +7 -0
  52. package/node_modules/@happier-dev/release-runtime/dist/minisign.d.ts.map +1 -0
  53. package/node_modules/@happier-dev/release-runtime/dist/minisign.js +92 -0
  54. package/node_modules/@happier-dev/release-runtime/dist/minisign.js.map +1 -0
  55. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.d.ts +26 -0
  56. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.d.ts.map +1 -0
  57. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.js +53 -0
  58. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.js.map +1 -0
  59. package/node_modules/@happier-dev/release-runtime/package.json +38 -0
  60. package/package.json +4 -2
  61. package/scripts/auth.mjs +3 -2
  62. package/scripts/auth_copy_from_pglite_lock_in_use.integration.test.mjs +1 -0
  63. package/scripts/auth_copy_from_runCapture.integration.test.mjs +8 -1
  64. package/scripts/build.mjs +3 -18
  65. package/scripts/bundleWorkspaceDeps.mjs +5 -1
  66. package/scripts/bundleWorkspaceDeps.test.mjs +16 -0
  67. package/scripts/mobile.mjs +32 -1
  68. package/scripts/mobile_prebuild_happyDir_defined.test.mjs +47 -0
  69. package/scripts/mobile_prebuild_sets_rct_metro_port.test.mjs +81 -0
  70. package/scripts/mobile_run_ios_passes_port.integration.test.mjs +101 -0
  71. package/scripts/providers_cmd.mjs +262 -0
  72. package/scripts/release_binary_smoke.integration.test.mjs +25 -6
  73. package/scripts/remote_cmd.mjs +240 -0
  74. package/scripts/self_host_daemon.real.integration.test.mjs +296 -0
  75. package/scripts/self_host_launchd.real.integration.test.mjs +211 -0
  76. package/scripts/self_host_runtime.mjs +1403 -312
  77. package/scripts/self_host_runtime.test.mjs +361 -1
  78. package/scripts/self_host_schtasks.real.integration.test.mjs +217 -0
  79. package/scripts/self_host_service_e2e_harness.mjs +93 -0
  80. package/scripts/self_host_systemd.real.integration.test.mjs +8 -86
  81. package/scripts/service.mjs +156 -26
  82. package/scripts/stack/command_arguments.mjs +1 -0
  83. package/scripts/stack/help_text.mjs +2 -0
  84. package/scripts/stack_daemon_cmd.integration.test.mjs +37 -0
  85. package/scripts/stack_happy_cmd.integration.test.mjs +36 -0
  86. package/scripts/utils/auth/credentials_paths.mjs +9 -9
  87. package/scripts/utils/auth/credentials_paths.test.mjs +8 -0
  88. package/scripts/utils/auth/stable_scope_id.mjs +1 -1
  89. package/scripts/utils/cli/cli_registry.mjs +18 -0
  90. package/scripts/utils/cli/progress.mjs +8 -1
  91. package/scripts/utils/cli/progress.test.mjs +43 -0
  92. package/scripts/utils/dev/expo_dev.buildEnv.test.mjs +17 -0
  93. package/scripts/utils/dev/expo_dev.mjs +35 -5
  94. package/scripts/utils/dev/expo_dev_restart_port_reservation.test.mjs +180 -1
  95. package/scripts/utils/dev/expo_dev_runtime_metadata.test.mjs +126 -0
  96. package/scripts/utils/dev/expo_dev_verbose_logs.test.mjs +9 -2
  97. package/scripts/utils/server/port.mjs +20 -2
  98. package/scripts/utils/service/service_manager.definition.test.mjs +66 -0
  99. package/scripts/utils/service/service_manager.mjs +96 -0
  100. package/scripts/utils/service/service_manager.plan.test.mjs +37 -0
  101. package/scripts/utils/service/service_manager.test.mjs +20 -0
  102. package/scripts/utils/service/systemd_service_unit.mjs +1 -0
  103. package/scripts/utils/service/systemd_service_unit.test.mjs +42 -0
  104. package/scripts/utils/service/windows_schtasks_wrapper.mjs +1 -0
  105. package/scripts/utils/service/windows_schtasks_wrapper.test.mjs +25 -0
  106. package/scripts/utils/ui/ui_export_env.mjs +29 -0
  107. package/scripts/utils/ui/ui_export_env.test.mjs +25 -0
  108. package/scripts/worktrees.mjs +3 -0
  109. package/scripts/worktrees_status_default_target.test.mjs +56 -0
@@ -0,0 +1,211 @@
1
+ import assert from 'node:assert/strict';
2
+ import { chmod, cp, mkdir, mkdtemp, rm } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ import test from 'node:test';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const SELF_HOST_INSTALL_TIMEOUT_MS = 420_000;
9
+
10
+ import { commandExists, extractBinaryFromArtifact, reserveLocalhostPort, run, waitForHealth } from './self_host_service_e2e_harness.mjs';
11
+
12
+ function currentTarget() {
13
+ if (process.platform !== 'darwin') return '';
14
+ if (process.arch === 'x64') return 'darwin-x64';
15
+ if (process.arch === 'arm64') return 'darwin-arm64';
16
+ return '';
17
+ }
18
+
19
+ function launchctlPrintTarget(label) {
20
+ const uid = typeof process.getuid === 'function' ? process.getuid() : null;
21
+ return uid != null ? `gui/${uid}/${label}` : label;
22
+ }
23
+
24
+ test(
25
+ 'compiled hstack self-host install/uninstall works on macOS launchd host without repo checkout',
26
+ { timeout: 15 * 60_000 },
27
+ async (t) => {
28
+ if (process.platform !== 'darwin') {
29
+ t.skip(`macos-only test (current: ${process.platform})`);
30
+ return;
31
+ }
32
+ const target = currentTarget();
33
+ if (!target) {
34
+ t.skip(`unsupported macOS runner architecture: ${process.arch}`);
35
+ return;
36
+ }
37
+ if (!commandExists('launchctl')) {
38
+ t.skip('launchctl is required');
39
+ return;
40
+ }
41
+ if (!commandExists('bun')) {
42
+ t.skip('bun is required to build compiled binaries');
43
+ return;
44
+ }
45
+
46
+ const repoRoot = resolve(fileURLToPath(new URL('../../..', import.meta.url)));
47
+ const version = `0.0.0-launchd.${Date.now()}`;
48
+
49
+ run(
50
+ process.execPath,
51
+ [
52
+ 'scripts/release/build-hstack-binaries.mjs',
53
+ '--channel=preview',
54
+ `--version=${version}`,
55
+ `--targets=${target}`,
56
+ ],
57
+ {
58
+ label: 'self-host-launchd',
59
+ cwd: repoRoot,
60
+ env: { ...process.env },
61
+ timeoutMs: 8 * 60_000,
62
+ }
63
+ );
64
+ run(
65
+ process.execPath,
66
+ [
67
+ 'scripts/release/build-server-binaries.mjs',
68
+ '--channel=preview',
69
+ `--version=${version}`,
70
+ `--targets=${target}`,
71
+ ],
72
+ {
73
+ label: 'self-host-launchd',
74
+ cwd: repoRoot,
75
+ env: { ...process.env },
76
+ timeoutMs: 8 * 60_000,
77
+ }
78
+ );
79
+
80
+ const hstackArtifact = join(repoRoot, 'dist', 'release-assets', 'stack', `hstack-v${version}-${target}.tar.gz`);
81
+ const serverArtifact = join(repoRoot, 'dist', 'release-assets', 'server', `happier-server-v${version}-${target}.tar.gz`);
82
+
83
+ const extractedHstack = await extractBinaryFromArtifact({ label: 'self-host-launchd', artifactPath: hstackArtifact, binaryName: 'hstack' });
84
+ const extractedServer = await extractBinaryFromArtifact({ label: 'self-host-launchd', artifactPath: serverArtifact, binaryName: 'happier-server' });
85
+
86
+ t.after(async () => {
87
+ await rm(extractedHstack.extractDir, { recursive: true, force: true });
88
+ await rm(extractedServer.extractDir, { recursive: true, force: true });
89
+ });
90
+
91
+ const sandboxDir = await mkdtemp(join(tmpdir(), 'happier-self-host-launchd-'));
92
+ t.after(async () => {
93
+ await rm(sandboxDir, { recursive: true, force: true });
94
+ });
95
+
96
+ const installRoot = join(sandboxDir, 'self-host');
97
+ const binDir = join(sandboxDir, 'bin');
98
+ const configDir = join(sandboxDir, 'config');
99
+ const dataDir = join(sandboxDir, 'data');
100
+ const logDir = join(sandboxDir, 'logs');
101
+ await mkdir(binDir, { recursive: true });
102
+
103
+ const hstackPath = join(binDir, 'hstack');
104
+ await cp(extractedHstack.binaryPath, hstackPath);
105
+ await chmod(hstackPath, 0o755);
106
+
107
+ const serviceName = `happier-server-e2e-${Date.now().toString(36).slice(-6)}`;
108
+ const serverPort = await reserveLocalhostPort();
109
+ const commonEnv = {
110
+ PATH: process.env.PATH ?? '',
111
+ HAPPIER_SELF_HOST_INSTALL_ROOT: installRoot,
112
+ HAPPIER_SELF_HOST_BIN_DIR: binDir,
113
+ HAPPIER_SELF_HOST_CONFIG_DIR: configDir,
114
+ HAPPIER_SELF_HOST_DATA_DIR: dataDir,
115
+ HAPPIER_SELF_HOST_LOG_DIR: logDir,
116
+ HAPPIER_SELF_HOST_SERVICE_NAME: serviceName,
117
+ HAPPIER_SELF_HOST_SERVER_BINARY: extractedServer.binaryPath,
118
+ HAPPIER_SELF_HOST_AUTO_UPDATE: '0',
119
+ HAPPIER_SELF_HOST_HEALTH_TIMEOUT_MS: '240000',
120
+ HAPPIER_NONINTERACTIVE: '1',
121
+ HAPPIER_WITH_CLI: '0',
122
+ HAPPIER_SERVER_PORT: String(serverPort),
123
+ HAPPIER_SERVER_HOST: '127.0.0.1',
124
+ };
125
+ const serverOutLog = join(logDir, 'server.out.log');
126
+ const serverErrLog = join(logDir, 'server.err.log');
127
+
128
+ let installSucceeded = false;
129
+ t.after(() => {
130
+ if (!installSucceeded) return;
131
+ run(
132
+ hstackPath,
133
+ ['self-host', 'uninstall', '--channel=preview', '--mode=user', '--yes', '--purge-data', '--json'],
134
+ {
135
+ env: commonEnv,
136
+ allowFail: true,
137
+ timeoutMs: 120_000,
138
+ stdio: 'ignore',
139
+ cwd: sandboxDir,
140
+ }
141
+ );
142
+ });
143
+
144
+ const installResult = run(
145
+ hstackPath,
146
+ ['self-host', 'install', '--channel=preview', '--mode=user', '--no-auto-update', '--non-interactive', '--without-cli', '--json'],
147
+ {
148
+ label: 'self-host-launchd',
149
+ env: commonEnv,
150
+ timeoutMs: SELF_HOST_INSTALL_TIMEOUT_MS,
151
+ allowFail: true,
152
+ cwd: sandboxDir,
153
+ }
154
+ );
155
+ if ((installResult.status ?? 1) !== 0) {
156
+ const recoveredHealth = await waitForHealth(`http://127.0.0.1:${serverPort}/v1/version`, 120_000);
157
+ if (!recoveredHealth) {
158
+ const statusResult = run(
159
+ hstackPath,
160
+ ['self-host', 'status', '--channel=preview', '--mode=user', '--json'],
161
+ { label: 'self-host-launchd', env: commonEnv, allowFail: true, timeoutMs: 45_000, cwd: sandboxDir }
162
+ );
163
+ const launchctlList = run('launchctl', ['list'], { label: 'self-host-launchd', allowFail: true, timeoutMs: 20_000 });
164
+ const launchctlPrint = run('launchctl', ['print', launchctlPrintTarget(serviceName)], { label: 'self-host-launchd', allowFail: true, timeoutMs: 20_000 });
165
+ const outTail = run('tail', ['-n', '200', serverOutLog], { label: 'self-host-launchd', allowFail: true, timeoutMs: 10_000 });
166
+ const errTail = run('tail', ['-n', '200', serverErrLog], { label: 'self-host-launchd', allowFail: true, timeoutMs: 10_000 });
167
+ throw new Error(
168
+ [
169
+ '[self-host-launchd] self-host install failed and service never became healthy',
170
+ `install status: ${String(installResult.status ?? 'null')}`,
171
+ `install stdout:\n${String(installResult.stdout ?? '').trim()}`,
172
+ `install stderr:\n${String(installResult.stderr ?? '').trim()}`,
173
+ `self-host status:\n${String(statusResult.stdout ?? '').trim()}\n${String(statusResult.stderr ?? '').trim()}`,
174
+ `launchctl list:\n${String(launchctlList.stdout ?? '').trim()}\n${String(launchctlList.stderr ?? '').trim()}`,
175
+ `launchctl print:\n${String(launchctlPrint.stdout ?? '').trim()}\n${String(launchctlPrint.stderr ?? '').trim()}`,
176
+ `server out tail (${serverOutLog}):\n${String(outTail.stdout ?? '').trim()}\n${String(outTail.stderr ?? '').trim()}`,
177
+ `server err tail (${serverErrLog}):\n${String(errTail.stdout ?? '').trim()}\n${String(errTail.stderr ?? '').trim()}`,
178
+ ].join('\n\n')
179
+ );
180
+ }
181
+ }
182
+ installSucceeded = true;
183
+
184
+ const healthOk = await waitForHealth(`http://127.0.0.1:${serverPort}/v1/version`, 90_000);
185
+ assert.equal(healthOk, true, 'self-host service health endpoint did not become ready');
186
+
187
+ const status = run(
188
+ hstackPath,
189
+ ['self-host', 'status', '--channel=preview', '--mode=user', '--json'],
190
+ { label: 'self-host-launchd', env: commonEnv, timeoutMs: 60_000, cwd: sandboxDir }
191
+ );
192
+ const statusPayload = JSON.parse(String(status.stdout ?? '').trim());
193
+ assert.equal(statusPayload?.ok, true);
194
+ assert.equal(statusPayload?.service?.name, serviceName);
195
+ assert.equal(statusPayload?.service?.active, true);
196
+ assert.equal(statusPayload?.healthy, true);
197
+
198
+ const launchctlPrintAfter = run('launchctl', ['print', launchctlPrintTarget(serviceName)], { label: 'self-host-launchd', allowFail: true, timeoutMs: 20_000 });
199
+ assert.equal(launchctlPrintAfter.status, 0, 'launchctl print should succeed after install');
200
+
201
+ run(
202
+ hstackPath,
203
+ ['self-host', 'uninstall', '--channel=preview', '--mode=user', '--yes', '--purge-data', '--json'],
204
+ { label: 'self-host-launchd', env: commonEnv, timeoutMs: 120_000, cwd: sandboxDir }
205
+ );
206
+ installSucceeded = false;
207
+
208
+ const launchctlPrintAfterUninstall = run('launchctl', ['print', launchctlPrintTarget(serviceName)], { label: 'self-host-launchd', allowFail: true, timeoutMs: 20_000 });
209
+ assert.notEqual(launchctlPrintAfterUninstall.status, 0, 'service should not remain registered after uninstall');
210
+ }
211
+ );