@dbx-tools/cli-service 0.9.40 → 0.9.46
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 +77 -34
- package/index.ts +5 -4
- package/lib/index.d.ts +5 -4
- package/lib/index.js +4 -3
- package/lib/src/_runtime.d.ts +2 -0
- package/lib/src/_runtime.js +20 -2
- package/lib/src/cli.d.ts +5 -0
- package/lib/src/cli.js +12 -6
- package/lib/src/definition.d.ts +29 -1
- package/lib/src/definition.js +42 -7
- package/lib/src/service.d.ts +10 -1
- package/lib/src/service.js +34 -11
- package/package.json +4 -3
- package/src/_runtime.ts +34 -1
- package/src/cli.ts +19 -7
- package/src/definition.ts +74 -8
- package/src/service.ts +64 -7
package/src/service.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This module owns current-user service compilation and lifecycle across
|
|
5
5
|
* consuming CLIs. Reuse {@link CliService} rather than adding product-specific
|
|
6
|
-
* installers, startup registration, runtime
|
|
6
|
+
* installers, uv Python environments, startup registration, runtime
|
|
7
|
+
* directories, or control sockets.
|
|
7
8
|
*
|
|
8
9
|
* @module
|
|
9
10
|
*/
|
|
@@ -26,7 +27,11 @@ import {
|
|
|
26
27
|
resolveServicePaths,
|
|
27
28
|
type ServiceRuntimeContext,
|
|
28
29
|
} from "./_paths.ts";
|
|
29
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
externalRuntimePackages,
|
|
32
|
+
installServicePythonPackage,
|
|
33
|
+
installServiceRuntime,
|
|
34
|
+
} from "./_runtime.ts";
|
|
30
35
|
import { installStartup, removeStartup, type ServiceLaunch } from "./_startup.ts";
|
|
31
36
|
import {
|
|
32
37
|
CliServiceDefinitionSchema,
|
|
@@ -54,6 +59,15 @@ export type CliServiceRuntimeInstaller = (
|
|
|
54
59
|
dependencies: Readonly<Record<string, string>>,
|
|
55
60
|
) => Promise<void>;
|
|
56
61
|
|
|
62
|
+
/** Install a Python package into a service-owned uv environment. */
|
|
63
|
+
export type CliServicePythonInstaller = (
|
|
64
|
+
uvExecutable: string,
|
|
65
|
+
directory: string,
|
|
66
|
+
packageSpecifier: string,
|
|
67
|
+
python: string,
|
|
68
|
+
platform: NodeJS.Platform,
|
|
69
|
+
) => Promise<string>;
|
|
70
|
+
|
|
57
71
|
/** Host runtime overrides for tests, embedded distributions, and nonstandard homes. */
|
|
58
72
|
export interface CliServiceRuntimeOptions {
|
|
59
73
|
/** Operating system used for configuration and startup registration. */
|
|
@@ -68,10 +82,14 @@ export interface CliServiceRuntimeOptions {
|
|
|
68
82
|
readonly globalHomeDirectory?: string;
|
|
69
83
|
/** Package-provided Bun executable override. */
|
|
70
84
|
readonly bunExecutable?: string;
|
|
85
|
+
/** uv executable used for managed Python package environments. */
|
|
86
|
+
readonly uvExecutable?: string;
|
|
71
87
|
/** Standalone compiler override. */
|
|
72
88
|
readonly compile?: CliServiceCompiler;
|
|
73
89
|
/** External runtime dependency installer override. */
|
|
74
90
|
readonly installRuntime?: CliServiceRuntimeInstaller;
|
|
91
|
+
/** Python package installer override. */
|
|
92
|
+
readonly installPython?: CliServicePythonInstaller;
|
|
75
93
|
/** System-tray host source entrypoint override. */
|
|
76
94
|
readonly hostEntrypoint?: string;
|
|
77
95
|
/** systray2 native executable override. */
|
|
@@ -119,8 +137,10 @@ export class CliService implements CliServiceLifecycle {
|
|
|
119
137
|
private readonly runtime: ServiceRuntimeContext;
|
|
120
138
|
private readonly globalHomeDirectory: string;
|
|
121
139
|
private readonly bunExecutable: string;
|
|
140
|
+
private readonly uvExecutable: string;
|
|
122
141
|
private readonly compiler: CliServiceCompiler;
|
|
123
142
|
private readonly runtimeInstaller: CliServiceRuntimeInstaller;
|
|
143
|
+
private readonly pythonInstaller: CliServicePythonInstaller;
|
|
124
144
|
private readonly hostEntrypoint: string;
|
|
125
145
|
private readonly trayExecutable: string;
|
|
126
146
|
|
|
@@ -142,11 +162,13 @@ export class CliService implements CliServiceLifecycle {
|
|
|
142
162
|
this.globalHomeDirectory =
|
|
143
163
|
options.globalHomeDirectory ?? join(this.runtime.homeDirectory, ".dbx-tools");
|
|
144
164
|
this.bunExecutable = options.bunExecutable ?? resolveBunExecutable();
|
|
165
|
+
this.uvExecutable = options.uvExecutable ?? "uv";
|
|
145
166
|
this.compiler =
|
|
146
167
|
options.compile ??
|
|
147
168
|
((entrypoint, output, workingDirectory, external) =>
|
|
148
169
|
compileWithBun(this.bunExecutable, entrypoint, output, workingDirectory, external));
|
|
149
170
|
this.runtimeInstaller = options.installRuntime ?? installServiceRuntime;
|
|
171
|
+
this.pythonInstaller = options.installPython ?? installServicePythonPackage;
|
|
150
172
|
this.hostEntrypoint = options.hostEntrypoint ?? resolveHostEntrypoint();
|
|
151
173
|
this.trayExecutable = options.trayExecutable ?? resolveTrayExecutable(this.runtime.platform);
|
|
152
174
|
}
|
|
@@ -162,7 +184,7 @@ export class CliService implements CliServiceLifecycle {
|
|
|
162
184
|
Object.fromEntries(Object.entries(dependencies).filter(([name]) => external.has(name))),
|
|
163
185
|
);
|
|
164
186
|
const paths = resolveServicePaths(this.definition, this.runtime);
|
|
165
|
-
const installedDefinition = await this.installDefinition(owner);
|
|
187
|
+
const installedDefinition = await this.installDefinition(owner, paths.directory);
|
|
166
188
|
const host = await this.ensureCompiledBinary(
|
|
167
189
|
this.binaryName(installedDefinition, "service"),
|
|
168
190
|
this.hostEntrypoint,
|
|
@@ -270,13 +292,39 @@ export class CliService implements CliServiceLifecycle {
|
|
|
270
292
|
};
|
|
271
293
|
}
|
|
272
294
|
|
|
273
|
-
private async installDefinition(
|
|
295
|
+
private async installDefinition(
|
|
296
|
+
owner: ServicePackage,
|
|
297
|
+
directory: string,
|
|
298
|
+
): Promise<CliServiceDefinition> {
|
|
274
299
|
const definition = CliServiceDefinitionSchema.parse({
|
|
275
300
|
...this.definition,
|
|
276
301
|
version: this.definition.version ?? owner.version,
|
|
277
302
|
});
|
|
303
|
+
if (!definition.version) throw new Error(`${definition.name} has no installable version`);
|
|
304
|
+
const pythonPackage = definition.pythonPackage
|
|
305
|
+
? {
|
|
306
|
+
...definition.pythonPackage,
|
|
307
|
+
version: definition.pythonPackage.version ?? definition.version,
|
|
308
|
+
}
|
|
309
|
+
: undefined;
|
|
310
|
+
const pythonEnvironment: Record<string, string> = {};
|
|
311
|
+
if (pythonPackage) {
|
|
312
|
+
pythonEnvironment.PYTHON = await this.pythonInstaller(
|
|
313
|
+
this.uvExecutable,
|
|
314
|
+
join(directory, "python"),
|
|
315
|
+
`${pythonPackage.name}==${pythonPackage.version}`,
|
|
316
|
+
pythonPackage.python,
|
|
317
|
+
this.runtime.platform,
|
|
318
|
+
);
|
|
319
|
+
}
|
|
278
320
|
const command = definition.command
|
|
279
|
-
? await this.installCommand(
|
|
321
|
+
? await this.installCommand(
|
|
322
|
+
definition,
|
|
323
|
+
owner,
|
|
324
|
+
definition.command,
|
|
325
|
+
"command",
|
|
326
|
+
pythonEnvironment,
|
|
327
|
+
)
|
|
280
328
|
: undefined;
|
|
281
329
|
const menu: CliServiceMenuItem[] = [];
|
|
282
330
|
for (const [index, item] of (definition.menu ?? []).entries()) {
|
|
@@ -289,6 +337,7 @@ export class CliService implements CliServiceLifecycle {
|
|
|
289
337
|
owner,
|
|
290
338
|
item.command,
|
|
291
339
|
`menu-${index + 1}`,
|
|
340
|
+
pythonEnvironment,
|
|
292
341
|
),
|
|
293
342
|
}
|
|
294
343
|
: item,
|
|
@@ -296,6 +345,7 @@ export class CliService implements CliServiceLifecycle {
|
|
|
296
345
|
}
|
|
297
346
|
return CliServiceDefinitionSchema.parse({
|
|
298
347
|
...definition,
|
|
348
|
+
...(pythonPackage ? { pythonPackage } : {}),
|
|
299
349
|
...(command ? { command } : {}),
|
|
300
350
|
...(menu.length > 0 ? { menu } : {}),
|
|
301
351
|
});
|
|
@@ -306,8 +356,15 @@ export class CliService implements CliServiceLifecycle {
|
|
|
306
356
|
owner: ServicePackage,
|
|
307
357
|
command: CliServiceCommand,
|
|
308
358
|
purpose: string,
|
|
359
|
+
runtimeEnvironment: Readonly<Record<string, string>>,
|
|
309
360
|
): Promise<CliServiceCommand> {
|
|
310
|
-
|
|
361
|
+
const environment = { ...command.environment, ...runtimeEnvironment };
|
|
362
|
+
if (command.executable) {
|
|
363
|
+
return {
|
|
364
|
+
...command,
|
|
365
|
+
...(Object.keys(environment).length > 0 ? { environment } : {}),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
311
368
|
const entrypoint = command.entrypoint ?? owner.bin(command.binName);
|
|
312
369
|
const installed = await this.ensureCompiledBinary(
|
|
313
370
|
this.binaryName(definition, purpose),
|
|
@@ -318,7 +375,7 @@ export class CliService implements CliServiceLifecycle {
|
|
|
318
375
|
return {
|
|
319
376
|
executable: installed.path,
|
|
320
377
|
...(command.arguments ? { arguments: command.arguments } : {}),
|
|
321
|
-
...(
|
|
378
|
+
...(Object.keys(environment).length > 0 ? { environment } : {}),
|
|
322
379
|
cwd: command.cwd ?? this.globalHomeDirectory,
|
|
323
380
|
};
|
|
324
381
|
}
|