@open-audio-stack/core 0.1.42 → 0.1.43
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 +24 -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,28 @@ 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
|
+
if (!(await commandExists('dpkg')))
|
|
182
|
+
excludedFormats.push(FileFormat.DebianPackage);
|
|
183
|
+
if (!(await commandExists('rpm')))
|
|
184
|
+
excludedFormats.push(FileFormat.RedHatPackage);
|
|
185
|
+
}
|
|
186
|
+
const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], excludedFormats);
|
|
187
|
+
if (!files.length)
|
|
188
|
+
throw new Error(`No compatible files found for ${slug}`);
|
|
177
189
|
// Elevate permissions if not running as admin.
|
|
178
190
|
if (!isAdmin() && !isTests()) {
|
|
179
191
|
let command = `--appDir "${this.config.get('appDir')}" --operation "install" --type "${this.type}" --id "${slug}"`;
|
|
@@ -194,19 +206,6 @@ export class ManagerLocal extends Manager {
|
|
|
194
206
|
// Create temporary directory to store downloaded files.
|
|
195
207
|
const dirDownloads = path.join(this.config.get('appDir'), 'downloads', this.type, slug, versionNum);
|
|
196
208
|
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
209
|
for (const key in files) {
|
|
211
210
|
// Download file to temporary directory if not already downloaded.
|
|
212
211
|
const file = files[key];
|
|
@@ -218,9 +217,10 @@ export class ManagerLocal extends Manager {
|
|
|
218
217
|
// Check file hash matches expected hash.
|
|
219
218
|
const hash = await fileHash(filePath);
|
|
220
219
|
if (hash !== file.sha256)
|
|
221
|
-
|
|
220
|
+
throw new Error(`${filePath} hash mismatch`);
|
|
222
221
|
// If installer, run the installer headless (without the user interface).
|
|
223
222
|
if (file.type === FileType.Installer) {
|
|
223
|
+
// Test time out if installing during tests.
|
|
224
224
|
if (isTests())
|
|
225
225
|
fileOpen(filePath);
|
|
226
226
|
else
|
|
@@ -324,26 +324,22 @@ export class ManagerLocal extends Manager {
|
|
|
324
324
|
// Get package information
|
|
325
325
|
const pkg = this.getPackage(slug);
|
|
326
326
|
if (!pkg) {
|
|
327
|
-
|
|
328
|
-
return false;
|
|
327
|
+
throw new Error(`Package ${slug} not found`);
|
|
329
328
|
}
|
|
330
329
|
const versionNum = version || pkg.latestVersion();
|
|
331
330
|
const pkgVersion = pkg.getVersion(versionNum);
|
|
332
331
|
if (!pkgVersion) {
|
|
333
|
-
|
|
334
|
-
return false;
|
|
332
|
+
throw new Error(`Package ${slug} version ${versionNum} not found`);
|
|
335
333
|
}
|
|
336
334
|
// Check if package is installed
|
|
337
335
|
if (!this.isPackageInstalled(slug, versionNum)) {
|
|
338
|
-
|
|
339
|
-
return false;
|
|
336
|
+
throw new Error(`Package ${slug} version ${versionNum} not installed`);
|
|
340
337
|
}
|
|
341
338
|
// Filter compatible files and find one with open field
|
|
342
339
|
const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], []);
|
|
343
340
|
const openableFile = files.find(file => file.open);
|
|
344
341
|
if (!openableFile) {
|
|
345
|
-
|
|
346
|
-
return false;
|
|
342
|
+
throw new Error(`Package ${slug} has no compatible file with open command defined`);
|
|
347
343
|
}
|
|
348
344
|
try {
|
|
349
345
|
const openPath = openableFile.open;
|
|
@@ -370,12 +366,7 @@ export class ManagerLocal extends Manager {
|
|
|
370
366
|
}
|
|
371
367
|
const command = `"${fullPath}" ${options.join(' ')}`;
|
|
372
368
|
this.log(`Running: ${command}`);
|
|
373
|
-
|
|
374
|
-
this.log(`Would run: ${command}`);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
fileOpen(fullPath);
|
|
378
|
-
}
|
|
369
|
+
fileOpen(fullPath, options);
|
|
379
370
|
return true;
|
|
380
371
|
}
|
|
381
372
|
catch (error) {
|
|
@@ -387,13 +378,13 @@ export class ManagerLocal extends Manager {
|
|
|
387
378
|
// Get package information from registry.
|
|
388
379
|
const pkg = this.getPackage(slug);
|
|
389
380
|
if (!pkg)
|
|
390
|
-
|
|
381
|
+
throw new Error(`Package ${slug} not found in registry`);
|
|
391
382
|
const versionNum = version || pkg.latestVersion();
|
|
392
383
|
const pkgVersion = pkg?.getVersion(versionNum);
|
|
393
384
|
if (!pkgVersion)
|
|
394
|
-
|
|
385
|
+
throw new Error(`Package ${slug} version ${versionNum} not found in registry`);
|
|
395
386
|
if (!this.isPackageInstalled(slug, versionNum))
|
|
396
|
-
|
|
387
|
+
throw new Error(`Package ${slug} version ${versionNum} not installed`);
|
|
397
388
|
// Elevate permissions if not running as admin.
|
|
398
389
|
if (!isAdmin() && !isTests()) {
|
|
399
390
|
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;
|