openpalm 0.9.6 → 0.9.8
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/bin/openpalm.js +5 -0
- package/package.json +3 -3
- package/src/commands/install-services.test.ts +24 -0
- package/src/commands/install-services.ts +13 -0
- package/src/commands/install.ts +5 -11
- package/src/main.test.ts +17 -1
- package/src/main.ts +1 -1
package/bin/openpalm.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openpalm",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"description": "OpenPalm CLI — install and manage a self-hosted OpenPalm stack",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"directory": "packages/cli"
|
|
11
11
|
},
|
|
12
12
|
"bin": {
|
|
13
|
-
"openpalm": "./
|
|
13
|
+
"openpalm": "./bin/openpalm.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"start": "bun run src/main.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"build:windows-arm64": "bun build src/main.ts --compile --target=bun-windows-arm64 --outfile dist/openpalm-cli-windows-arm64.exe"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@openpalm/lib": "
|
|
27
|
+
"@openpalm/lib": "0.9.6",
|
|
28
28
|
"citty": "^0.2.1"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { buildDeployStatusEntries, buildInstallServiceNames } from './install-services.ts';
|
|
3
|
+
|
|
4
|
+
describe('install service helpers', () => {
|
|
5
|
+
it('appends admin services to managed services', () => {
|
|
6
|
+
expect(buildInstallServiceNames(['caddy', 'memory'])).toEqual([
|
|
7
|
+
'caddy',
|
|
8
|
+
'memory',
|
|
9
|
+
'admin',
|
|
10
|
+
'docker-socket-proxy',
|
|
11
|
+
]);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('builds deploy status entries for the full install service list', () => {
|
|
15
|
+
const services = buildInstallServiceNames(['caddy', 'memory']);
|
|
16
|
+
|
|
17
|
+
expect(buildDeployStatusEntries(services, 'pending', 'Waiting...')).toEqual([
|
|
18
|
+
{ service: 'caddy', status: 'pending', label: 'Waiting...' },
|
|
19
|
+
{ service: 'memory', status: 'pending', label: 'Waiting...' },
|
|
20
|
+
{ service: 'admin', status: 'pending', label: 'Waiting...' },
|
|
21
|
+
{ service: 'docker-socket-proxy', status: 'pending', label: 'Waiting...' },
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type DeployStatusState = 'pending' | 'pulling';
|
|
2
|
+
|
|
3
|
+
export function buildInstallServiceNames(managedServices: string[]): string[] {
|
|
4
|
+
return [...managedServices, 'admin', 'docker-socket-proxy'];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function buildDeployStatusEntries(
|
|
8
|
+
services: string[],
|
|
9
|
+
status: DeployStatusState,
|
|
10
|
+
label: string,
|
|
11
|
+
): Array<{ service: string; status: DeployStatusState; label: string }> {
|
|
12
|
+
return services.map(service => ({ service, status, label }));
|
|
13
|
+
}
|
package/src/commands/install.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { detectHostInfo } from '../lib/host-info.ts';
|
|
|
12
12
|
import { loadAdminToken } from '../lib/env.ts';
|
|
13
13
|
import { ensureStagedState, fullComposeArgs, buildManagedServiceNames } from '../lib/staging.ts';
|
|
14
14
|
import { createSetupServer } from '../setup-wizard/server.ts';
|
|
15
|
+
import { buildInstallServiceNames, buildDeployStatusEntries } from './install-services.ts';
|
|
15
16
|
|
|
16
17
|
const DEFAULT_INSTALL_REF = cliPkg.version ? `v${cliPkg.version}` : 'main';
|
|
17
18
|
const SETUP_WIZARD_PORT = 8100;
|
|
@@ -220,22 +221,15 @@ export async function bootstrapInstall(options: InstallOptions): Promise<void> {
|
|
|
220
221
|
const state = await ensureStagedState();
|
|
221
222
|
const composeArgs = fullComposeArgs(state);
|
|
222
223
|
const managedServices = buildManagedServiceNames(state);
|
|
224
|
+
const allServices = buildInstallServiceNames(managedServices);
|
|
223
225
|
|
|
224
|
-
wizard.updateDeployStatus(
|
|
225
|
-
allServices.map(s => ({ service: s, status: 'pending', label: 'Waiting...' })),
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
// Include admin profile so admin + docker-socket-proxy start by default
|
|
229
|
-
const adminServices = ['admin', 'docker-socket-proxy'];
|
|
230
|
-
const allServices = [...managedServices, ...adminServices];
|
|
226
|
+
wizard.updateDeployStatus(buildDeployStatusEntries(allServices, 'pending', 'Waiting...'));
|
|
231
227
|
|
|
232
228
|
await runDockerCompose([...composeArgs, '--profile', 'admin', 'pull', ...allServices]).catch(() => {
|
|
233
229
|
// Pull failure is non-fatal — images may already be cached
|
|
234
230
|
});
|
|
235
231
|
|
|
236
|
-
wizard.updateDeployStatus(
|
|
237
|
-
allServices.map(s => ({ service: s, status: 'pulling', label: 'Starting...' })),
|
|
238
|
-
);
|
|
232
|
+
wizard.updateDeployStatus(buildDeployStatusEntries(allServices, 'pulling', 'Starting...'));
|
|
239
233
|
|
|
240
234
|
await runDockerCompose([...composeArgs, '--profile', 'admin', 'up', '-d', ...allServices]);
|
|
241
235
|
|
|
@@ -268,7 +262,7 @@ export async function bootstrapInstall(options: InstallOptions): Promise<void> {
|
|
|
268
262
|
const state = await ensureStagedState();
|
|
269
263
|
const composeArgs = fullComposeArgs(state);
|
|
270
264
|
const managedServices = buildManagedServiceNames(state);
|
|
271
|
-
const allServices =
|
|
265
|
+
const allServices = buildInstallServiceNames(managedServices);
|
|
272
266
|
|
|
273
267
|
await runDockerCompose([...composeArgs, '--profile', 'admin', 'up', '-d', ...allServices]);
|
|
274
268
|
|
package/src/main.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it, mock } from 'bun:test';
|
|
2
|
-
import { existsSync, mkdirSync, writeFileSync, chmodSync, mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync, chmodSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { detectHostInfo, main, reconcileStackEnvImageTag, resolveRequestedImageTag, upsertEnvValue } from './main.ts';
|
|
@@ -237,6 +237,22 @@ describe('cli main', () => {
|
|
|
237
237
|
});
|
|
238
238
|
});
|
|
239
239
|
|
|
240
|
+
describe('npm bin launcher', () => {
|
|
241
|
+
it('points the published bin to a Bun launcher script instead of a TypeScript source file', () => {
|
|
242
|
+
const cliPkg = JSON.parse(
|
|
243
|
+
readFileSync(new URL('../package.json', import.meta.url), 'utf8'),
|
|
244
|
+
) as {
|
|
245
|
+
bin?: Record<string, string>;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
expect(cliPkg.bin?.openpalm).toBe('./bin/openpalm.js');
|
|
249
|
+
|
|
250
|
+
const launcher = readFileSync(new URL('../bin/openpalm.js', import.meta.url), 'utf8');
|
|
251
|
+
|
|
252
|
+
expect(launcher.startsWith('#!/usr/bin/env bun\n')).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
240
256
|
describe('validate command', () => {
|
|
241
257
|
it('is a recognized command (does not throw Unknown command)', async () => {
|
|
242
258
|
const tempStateHome = mkdtempSync(join(tmpdir(), 'openpalm-test-'));
|
package/src/main.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type { HostInfo } from './lib/host-info.ts';
|
|
|
8
8
|
export { upsertEnvValue, resolveRequestedImageTag, reconcileStackEnvImageTag } from './lib/env.ts';
|
|
9
9
|
export { bootstrapInstall } from './commands/install.ts';
|
|
10
10
|
|
|
11
|
-
const mainCommand = defineCommand({
|
|
11
|
+
export const mainCommand = defineCommand({
|
|
12
12
|
meta: {
|
|
13
13
|
name: 'openpalm',
|
|
14
14
|
version: cliPkg.version,
|