@open-audio-stack/core 0.1.42 → 0.1.44
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/build/classes/Manager.d.ts +1 -1
- package/build/classes/Manager.js +14 -10
- package/build/classes/ManagerLocal.d.ts +2 -2
- package/build/classes/ManagerLocal.js +32 -33
- package/build/helpers/file.d.ts +1 -1
- package/build/helpers/file.js +20 -8
- package/build/types/PluginFormat.d.ts +3 -1
- package/build/types/PluginFormat.js +1 -0
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ export declare class Manager extends Base {
|
|
|
14
14
|
getPackage(slug: string): Package | undefined;
|
|
15
15
|
getReport(): ManagerReport;
|
|
16
16
|
outputReport(): void;
|
|
17
|
-
listPackages(installed?: boolean): Package[];
|
|
17
|
+
listPackages(installed?: boolean, showAll?: boolean): Package[];
|
|
18
18
|
removePackage(slug: string): void;
|
|
19
19
|
reset(): void;
|
|
20
20
|
search(query: string): Package[];
|
package/build/classes/Manager.js
CHANGED
|
@@ -2,6 +2,8 @@ import { apiJson } from '../helpers/api.js';
|
|
|
2
2
|
import { Config } from './Config.js';
|
|
3
3
|
import { Package } from './Package.js';
|
|
4
4
|
import { Base } from './Base.js';
|
|
5
|
+
import { packageCompatibleFiles } from '../helpers/package.js';
|
|
6
|
+
import { getArchitecture, getSystem } from '../helpers/utilsLocal.js';
|
|
5
7
|
export class Manager extends Base {
|
|
6
8
|
config;
|
|
7
9
|
packages;
|
|
@@ -52,19 +54,21 @@ export class Manager extends Base {
|
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
|
-
listPackages(installed) {
|
|
57
|
+
listPackages(installed, showAll = false) {
|
|
58
|
+
let packages = Array.from(this.packages.values());
|
|
56
59
|
if (installed !== undefined) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
packages = packages.filter(pkg => Array.from(pkg.versions.values()).some(pkgVersion => (installed === true && pkgVersion.installed) || (installed === false && !pkgVersion.installed)));
|
|
61
|
+
}
|
|
62
|
+
if (!showAll) {
|
|
63
|
+
packages = packages.filter(pkg => {
|
|
64
|
+
const pkgVersion = pkg.getVersionLatest();
|
|
65
|
+
if (!pkgVersion)
|
|
66
|
+
return false;
|
|
67
|
+
const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], []);
|
|
68
|
+
return files.length > 0;
|
|
64
69
|
});
|
|
65
|
-
return packagesFiltered;
|
|
66
70
|
}
|
|
67
|
-
return
|
|
71
|
+
return packages.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
68
72
|
}
|
|
69
73
|
removePackage(slug) {
|
|
70
74
|
if (!this.packages.has(slug))
|
|
@@ -10,12 +10,12 @@ export declare class ManagerLocal extends Manager {
|
|
|
10
10
|
create(): Promise<void>;
|
|
11
11
|
scan(ext?: string, installable?: boolean): void;
|
|
12
12
|
export(dir: string, ext?: string): boolean;
|
|
13
|
-
install(slug: string, version?: string): Promise<
|
|
13
|
+
install(slug: string, version?: string): Promise<PackageVersion>;
|
|
14
14
|
installAll(): Promise<Package[]>;
|
|
15
15
|
installDependency(slug: string, version?: string, filePath?: string, type?: RegistryType): Promise<any>;
|
|
16
16
|
installDependencies(filePath: string, type?: RegistryType): Promise<any>;
|
|
17
17
|
open(slug: string, version?: string, options?: string[]): boolean;
|
|
18
|
-
uninstall(slug: string, version?: string): Promise<
|
|
18
|
+
uninstall(slug: string, version?: string): Promise<PackageVersion>;
|
|
19
19
|
uninstallDependency(slug: string, version?: string, filePath?: string, type?: RegistryType): Promise<any>;
|
|
20
20
|
uninstallDependencies(filePath?: string, type?: RegistryType): Promise<any>;
|
|
21
21
|
}
|
|
@@ -164,16 +164,36 @@ export class ManagerLocal extends Manager {
|
|
|
164
164
|
// Get package information from registry.
|
|
165
165
|
const pkg = this.getPackage(slug);
|
|
166
166
|
if (!pkg)
|
|
167
|
-
|
|
167
|
+
throw new Error(`Package ${slug} not found in registry`);
|
|
168
168
|
const versionNum = version || pkg.latestVersion();
|
|
169
169
|
const pkgVersion = pkg?.getVersion(versionNum);
|
|
170
170
|
if (!pkgVersion)
|
|
171
|
-
|
|
171
|
+
throw new Error(`Package ${slug} version ${versionNum} not found in registry`);
|
|
172
172
|
if (this.isPackageInstalled(slug, versionNum)) {
|
|
173
173
|
this.log(`Package ${slug} version ${versionNum} already installed`);
|
|
174
174
|
pkgVersion.installed = true;
|
|
175
175
|
return pkgVersion;
|
|
176
176
|
}
|
|
177
|
+
// Check for compatible files before running admin command
|
|
178
|
+
const excludedFormats = [];
|
|
179
|
+
const system = getSystem();
|
|
180
|
+
if (system === SystemType.Linux) {
|
|
181
|
+
const hasDpkg = await commandExists('dpkg');
|
|
182
|
+
const hasRpm = await commandExists('rpm');
|
|
183
|
+
// If both exist, prefer DEB over RPM
|
|
184
|
+
if (hasDpkg && hasRpm) {
|
|
185
|
+
excludedFormats.push(FileFormat.RedHatPackage);
|
|
186
|
+
}
|
|
187
|
+
else if (!hasDpkg) {
|
|
188
|
+
excludedFormats.push(FileFormat.DebianPackage);
|
|
189
|
+
}
|
|
190
|
+
else if (!hasRpm) {
|
|
191
|
+
excludedFormats.push(FileFormat.RedHatPackage);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], excludedFormats);
|
|
195
|
+
if (!files.length)
|
|
196
|
+
throw new Error(`No compatible files found for ${slug}`);
|
|
177
197
|
// Elevate permissions if not running as admin.
|
|
178
198
|
if (!isAdmin() && !isTests()) {
|
|
179
199
|
let command = `--appDir "${this.config.get('appDir')}" --operation "install" --type "${this.type}" --id "${slug}"`;
|
|
@@ -194,19 +214,6 @@ export class ManagerLocal extends Manager {
|
|
|
194
214
|
// Create temporary directory to store downloaded files.
|
|
195
215
|
const dirDownloads = path.join(this.config.get('appDir'), 'downloads', this.type, slug, versionNum);
|
|
196
216
|
dirCreate(dirDownloads);
|
|
197
|
-
// Not all Linux distributions support all file formats.
|
|
198
|
-
const excludedFormats = [];
|
|
199
|
-
const system = getSystem();
|
|
200
|
-
if (system === SystemType.Linux) {
|
|
201
|
-
if (!(await commandExists('dpkg')))
|
|
202
|
-
excludedFormats.push(FileFormat.DebianPackage);
|
|
203
|
-
if (!(await commandExists('rpm')))
|
|
204
|
-
excludedFormats.push(FileFormat.RedHatPackage);
|
|
205
|
-
}
|
|
206
|
-
// Filter for compatible files and download.
|
|
207
|
-
const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], excludedFormats);
|
|
208
|
-
if (!files.length)
|
|
209
|
-
return this.log(`Error: No compatible files found for ${slug}`);
|
|
210
217
|
for (const key in files) {
|
|
211
218
|
// Download file to temporary directory if not already downloaded.
|
|
212
219
|
const file = files[key];
|
|
@@ -218,9 +225,10 @@ export class ManagerLocal extends Manager {
|
|
|
218
225
|
// Check file hash matches expected hash.
|
|
219
226
|
const hash = await fileHash(filePath);
|
|
220
227
|
if (hash !== file.sha256)
|
|
221
|
-
|
|
228
|
+
throw new Error(`${filePath} hash mismatch`);
|
|
222
229
|
// If installer, run the installer headless (without the user interface).
|
|
223
230
|
if (file.type === FileType.Installer) {
|
|
231
|
+
// Test time out if installing during tests.
|
|
224
232
|
if (isTests())
|
|
225
233
|
fileOpen(filePath);
|
|
226
234
|
else
|
|
@@ -324,26 +332,22 @@ export class ManagerLocal extends Manager {
|
|
|
324
332
|
// Get package information
|
|
325
333
|
const pkg = this.getPackage(slug);
|
|
326
334
|
if (!pkg) {
|
|
327
|
-
|
|
328
|
-
return false;
|
|
335
|
+
throw new Error(`Package ${slug} not found`);
|
|
329
336
|
}
|
|
330
337
|
const versionNum = version || pkg.latestVersion();
|
|
331
338
|
const pkgVersion = pkg.getVersion(versionNum);
|
|
332
339
|
if (!pkgVersion) {
|
|
333
|
-
|
|
334
|
-
return false;
|
|
340
|
+
throw new Error(`Package ${slug} version ${versionNum} not found`);
|
|
335
341
|
}
|
|
336
342
|
// Check if package is installed
|
|
337
343
|
if (!this.isPackageInstalled(slug, versionNum)) {
|
|
338
|
-
|
|
339
|
-
return false;
|
|
344
|
+
throw new Error(`Package ${slug} version ${versionNum} not installed`);
|
|
340
345
|
}
|
|
341
346
|
// Filter compatible files and find one with open field
|
|
342
347
|
const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], []);
|
|
343
348
|
const openableFile = files.find(file => file.open);
|
|
344
349
|
if (!openableFile) {
|
|
345
|
-
|
|
346
|
-
return false;
|
|
350
|
+
throw new Error(`Package ${slug} has no compatible file with open command defined`);
|
|
347
351
|
}
|
|
348
352
|
try {
|
|
349
353
|
const openPath = openableFile.open;
|
|
@@ -370,12 +374,7 @@ export class ManagerLocal extends Manager {
|
|
|
370
374
|
}
|
|
371
375
|
const command = `"${fullPath}" ${options.join(' ')}`;
|
|
372
376
|
this.log(`Running: ${command}`);
|
|
373
|
-
|
|
374
|
-
this.log(`Would run: ${command}`);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
fileOpen(fullPath);
|
|
378
|
-
}
|
|
377
|
+
fileOpen(fullPath, options);
|
|
379
378
|
return true;
|
|
380
379
|
}
|
|
381
380
|
catch (error) {
|
|
@@ -387,13 +386,13 @@ export class ManagerLocal extends Manager {
|
|
|
387
386
|
// Get package information from registry.
|
|
388
387
|
const pkg = this.getPackage(slug);
|
|
389
388
|
if (!pkg)
|
|
390
|
-
|
|
389
|
+
throw new Error(`Package ${slug} not found in registry`);
|
|
391
390
|
const versionNum = version || pkg.latestVersion();
|
|
392
391
|
const pkgVersion = pkg?.getVersion(versionNum);
|
|
393
392
|
if (!pkgVersion)
|
|
394
|
-
|
|
393
|
+
throw new Error(`Package ${slug} version ${versionNum} not found in registry`);
|
|
395
394
|
if (!this.isPackageInstalled(slug, versionNum))
|
|
396
|
-
|
|
395
|
+
throw new Error(`Package ${slug} version ${versionNum} not installed`);
|
|
397
396
|
// Elevate permissions if not running as admin.
|
|
398
397
|
if (!isAdmin() && !isTests()) {
|
|
399
398
|
let command = `--appDir "${this.config.get('appDir')}" --operation "uninstall" --type "${this.type}" --id "${slug}"`;
|
package/build/helpers/file.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare function fileHash(filePath: string, algorithm?: string): Promise<
|
|
|
33
33
|
export declare function fileInstall(filePath: string): Buffer<ArrayBufferLike>;
|
|
34
34
|
export declare function fileMove(filePath: string, newPath: string): void | boolean;
|
|
35
35
|
export declare function filesMove(dirSource: string, dirTarget: string, dirSub: string, formatDir: Record<string, string>): string[];
|
|
36
|
-
export declare function fileOpen(filePath: string): Buffer<ArrayBufferLike>;
|
|
36
|
+
export declare function fileOpen(filePath: string, options?: string[]): import("child_process").ChildProcess | Buffer<ArrayBufferLike>;
|
|
37
37
|
export declare function fileRead(filePath: string): string;
|
|
38
38
|
export declare function fileReadJson(filePath: string): any;
|
|
39
39
|
export declare function fileReadString(filePath: string): string;
|
package/build/helpers/file.js
CHANGED
|
@@ -247,8 +247,9 @@ export function fileMove(filePath, newPath) {
|
|
|
247
247
|
return false;
|
|
248
248
|
}
|
|
249
249
|
export function filesMove(dirSource, dirTarget, dirSub, formatDir) {
|
|
250
|
-
// Read files from source directory, ignoring Mac Contents files.
|
|
251
|
-
const
|
|
250
|
+
// Read all files from source directory, ignoring Mac Contents files.
|
|
251
|
+
const allFiles = dirRead(`${dirSource}/**/*`);
|
|
252
|
+
const files = allFiles.filter(f => !dirIs(f));
|
|
252
253
|
const filesMoved = [];
|
|
253
254
|
// For each file, move to correct folder based on type
|
|
254
255
|
files.forEach((fileSource) => {
|
|
@@ -256,7 +257,7 @@ export function filesMove(dirSource, dirTarget, dirSub, formatDir) {
|
|
|
256
257
|
const fileExtTarget = formatDir[fileExt];
|
|
257
258
|
// If this is not a supported file format, then ignore.
|
|
258
259
|
if (fileExtTarget === undefined)
|
|
259
|
-
return log(`${fileSource} - ${fileExt} not mapped to a installation folder, skipping.`);
|
|
260
|
+
return log(`${fileSource} - ${fileExt || 'no extension'} not mapped to a installation folder, skipping.`);
|
|
260
261
|
const fileTarget = path.join(dirTarget, fileExtTarget, dirSub, path.basename(fileSource));
|
|
261
262
|
if (fileExists(fileTarget))
|
|
262
263
|
return log(`${fileSource} - ${fileTarget} already exists, skipping.`);
|
|
@@ -270,21 +271,32 @@ export function filesMove(dirSource, dirTarget, dirSub, formatDir) {
|
|
|
270
271
|
fileExec(executablePath);
|
|
271
272
|
}
|
|
272
273
|
}
|
|
273
|
-
else if (['elf', 'exe'].includes(fileExt)) {
|
|
274
|
+
else if (['elf', 'exe', ''].includes(fileExt)) {
|
|
274
275
|
fileExec(fileTarget);
|
|
275
276
|
}
|
|
276
277
|
filesMoved.push(fileTarget);
|
|
277
278
|
});
|
|
278
279
|
return filesMoved;
|
|
279
280
|
}
|
|
280
|
-
export function fileOpen(filePath) {
|
|
281
|
-
let command = '';
|
|
281
|
+
export function fileOpen(filePath, options = []) {
|
|
282
282
|
if (process.env.CI)
|
|
283
283
|
return Buffer.from('');
|
|
284
|
+
if (getSystem() === SystemType.Mac) {
|
|
285
|
+
const isExecutable = !path.extname(filePath);
|
|
286
|
+
if (isExecutable) {
|
|
287
|
+
// Use spawn for executables with stdio inherit to show output
|
|
288
|
+
log('⎋', `spawn "${filePath}" ${options.join(' ')}`);
|
|
289
|
+
const child = spawn(filePath, options, { stdio: 'inherit' });
|
|
290
|
+
return child;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
log('⎋', `open "${filePath}"`);
|
|
294
|
+
return execSync(`open "${filePath}"`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
let command = '';
|
|
284
298
|
if (getSystem() === SystemType.Win)
|
|
285
299
|
command = 'start ""';
|
|
286
|
-
else if (getSystem() === SystemType.Mac)
|
|
287
|
-
command = 'open';
|
|
288
300
|
else
|
|
289
301
|
command = 'xdg-open';
|
|
290
302
|
log('⎋', `${command} "${filePath}"`);
|
|
@@ -19,7 +19,9 @@ export declare enum PluginFormat {
|
|
|
19
19
|
export type PluginFormatDir = {
|
|
20
20
|
[format in PluginFormat]: string;
|
|
21
21
|
};
|
|
22
|
-
export declare const pluginFormatDir: PluginFormatDir
|
|
22
|
+
export declare const pluginFormatDir: PluginFormatDir & {
|
|
23
|
+
'': string;
|
|
24
|
+
};
|
|
23
25
|
export interface PluginFormatOption {
|
|
24
26
|
description: string;
|
|
25
27
|
value: PluginFormat;
|