@open-audio-stack/core 0.1.20 → 0.1.22

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.
@@ -1,10 +1,10 @@
1
1
  import { PackageValidationRec } from '../types/Package.js';
2
2
  import { ZodIssue } from 'zod';
3
3
  export declare class Base {
4
- debug: boolean;
4
+ get debug(): boolean;
5
5
  log(...args: any): void;
6
- logEnable(): boolean;
7
- logDisable(): boolean;
6
+ logEnable(): void;
7
+ logDisable(): void;
8
8
  logErrors(errors: ZodIssue[]): void;
9
9
  logRecommendations(recs: PackageValidationRec[]): void;
10
10
  logReport(info: string, errors?: ZodIssue[], recs?: PackageValidationRec[]): void;
@@ -1,46 +1,24 @@
1
- import chalk from 'chalk';
2
- import { logEnable, logDisable } from '../helpers/utils.js';
1
+ import { Logger } from './Logger.js';
3
2
  export class Base {
4
- debug = false;
3
+ get debug() {
4
+ return Logger.debug;
5
+ }
5
6
  log(...args) {
6
- if (this.debug)
7
- console.log(...args);
7
+ Logger.log(...args);
8
8
  }
9
9
  logEnable() {
10
- logEnable();
11
- return (this.debug = true);
10
+ Logger.logEnable();
12
11
  }
13
12
  logDisable() {
14
- logDisable();
15
- return (this.debug = false);
13
+ Logger.logDisable();
16
14
  }
17
15
  logErrors(errors) {
18
- errors.forEach(error => {
19
- // @ts-expect-error need to filter by code.
20
- if (error.received) {
21
- this.log(chalk.red(
22
- // @ts-expect-error need to filter by code.
23
- `- ${error.path} (${error.message}) received '${error.received}' expected '${error.expected}'`));
24
- }
25
- else {
26
- this.log(chalk.red(`- ${error.path} (${error.message})`));
27
- }
28
- });
16
+ Logger.logErrors(errors);
29
17
  }
30
18
  logRecommendations(recs) {
31
- recs.forEach(rec => {
32
- this.log(chalk.yellow(`- ${rec.field} ${rec.rec}`));
33
- });
19
+ Logger.logRecommendations(recs);
34
20
  }
35
21
  logReport(info, errors, recs) {
36
- if (errors && errors.length > 0) {
37
- this.log(chalk.red(`X ${info}`));
38
- this.logErrors(errors);
39
- }
40
- else {
41
- this.log(chalk.green(`✓ ${info}`));
42
- }
43
- if (recs)
44
- this.logRecommendations(recs);
22
+ Logger.logReport(info, errors, recs);
45
23
  }
46
24
  }
@@ -0,0 +1,11 @@
1
+ import { PackageValidationRec } from '../types/Package.js';
2
+ import { ZodIssue } from 'zod';
3
+ export declare class Logger {
4
+ static debug: boolean;
5
+ static log(...args: any): void;
6
+ static logEnable(): boolean;
7
+ static logDisable(): boolean;
8
+ static logErrors(errors: ZodIssue[]): void;
9
+ static logRecommendations(recs: PackageValidationRec[]): void;
10
+ static logReport(info: string, errors?: ZodIssue[], recs?: PackageValidationRec[]): void;
11
+ }
@@ -0,0 +1,46 @@
1
+ import chalk from 'chalk';
2
+ import { logEnable, logDisable } from '../helpers/utils.js';
3
+ export class Logger {
4
+ static debug = false;
5
+ static log(...args) {
6
+ if (this.debug)
7
+ console.log(...args);
8
+ }
9
+ static logEnable() {
10
+ logEnable();
11
+ return (this.debug = true);
12
+ }
13
+ static logDisable() {
14
+ logDisable();
15
+ return (this.debug = false);
16
+ }
17
+ static logErrors(errors) {
18
+ errors.forEach(error => {
19
+ // @ts-expect-error need to filter by code.
20
+ if (error.received) {
21
+ this.log(chalk.red(
22
+ // @ts-expect-error need to filter by code.
23
+ `- ${error.path} (${error.message}) received '${error.received}' expected '${error.expected}'`));
24
+ }
25
+ else {
26
+ this.log(chalk.red(`- ${error.path} (${error.message})`));
27
+ }
28
+ });
29
+ }
30
+ static logRecommendations(recs) {
31
+ recs.forEach(rec => {
32
+ this.log(chalk.yellow(`- ${rec.field} ${rec.rec}`));
33
+ });
34
+ }
35
+ static logReport(info, errors, recs) {
36
+ if (errors && errors.length > 0) {
37
+ this.log(chalk.red(`X ${info}`));
38
+ this.logErrors(errors);
39
+ }
40
+ else {
41
+ this.log(chalk.green(`✓ ${info}`));
42
+ }
43
+ if (recs)
44
+ this.logRecommendations(recs);
45
+ }
46
+ }
@@ -1,7 +1,7 @@
1
1
  import path from 'path';
2
2
  import { Package } from './Package.js';
3
3
  import { Manager } from './Manager.js';
4
- import { archiveExtract, dirCreate, dirDelete, dirEmpty, dirRead, fileCreate, fileCreateJson, fileCreateYaml, fileExists, fileHash, fileInstall, fileOpen, fileReadJson, fileReadYaml, filesMove, isAdmin, runCliAsAdmin, } from '../helpers/file.js';
4
+ import { archiveExtract, dirCreate, dirDelete, dirEmpty, dirMove, dirRead, fileCreate, fileCreateJson, fileCreateYaml, fileExists, fileHash, fileInstall, fileOpen, fileReadJson, fileReadYaml, filesMove, isAdmin, runCliAsAdmin, } from '../helpers/file.js';
5
5
  import { isValidVersion, pathGetSlug, pathGetVersion, toSlug } from '../helpers/utils.js';
6
6
  import { commandExists, getArchitecture, getSystem, isTests } from '../helpers/utilsLocal.js';
7
7
  import { apiBuffer } from '../helpers/api.js';
@@ -14,7 +14,7 @@ import { presetFormatDir } from '../types/PresetFormat.js';
14
14
  import { projectFormatDir } from '../types/ProjectFormat.js';
15
15
  import { FileFormat } from '../types/FileFormat.js';
16
16
  import { licenses } from '../types/License.js';
17
- import { pluginTypes } from '../types/PluginType.js';
17
+ import { PluginType, pluginTypes } from '../types/PluginType.js';
18
18
  import { presetTypes } from '../types/PresetType.js';
19
19
  import { projectTypes } from '../types/ProjectType.js';
20
20
  import { SystemType } from '../types/SystemType.js';
@@ -114,7 +114,11 @@ export class ManagerLocal extends Manager {
114
114
  scan(ext = 'json', installable = true) {
115
115
  const filePaths = dirRead(`${this.typeDir}/**/index.${ext}`);
116
116
  filePaths.forEach((filePath) => {
117
- const subPath = filePath.replace(`${this.typeDir}/`, '');
117
+ let subPath = filePath.replace(`${this.typeDir}/`, '');
118
+ // TODO improve this code.
119
+ const parts = subPath.split('/');
120
+ parts.shift();
121
+ subPath = parts.join('/');
118
122
  const pkgJson = ext === 'yaml' ? fileReadYaml(filePath) : fileReadJson(filePath);
119
123
  if (installable)
120
124
  pkgJson.installed = true;
@@ -151,6 +155,7 @@ export class ManagerLocal extends Manager {
151
155
  return true;
152
156
  }
153
157
  async install(slug, version) {
158
+ this.log('install', slug, version);
154
159
  // Get package information from registry.
155
160
  const pkg = this.getPackage(slug);
156
161
  if (!pkg)
@@ -159,13 +164,17 @@ export class ManagerLocal extends Manager {
159
164
  const pkgVersion = pkg?.getVersion(versionNum);
160
165
  if (!pkgVersion)
161
166
  return this.log(`Package ${slug} version ${versionNum} not found in registry`);
162
- if (pkgVersion.installed)
167
+ if (pkgVersion.installed) {
168
+ this.log(`Package ${slug} version ${versionNum} already installed`);
163
169
  return pkgVersion;
170
+ }
164
171
  // Elevate permissions if not running as admin.
165
172
  if (!isAdmin() && !isTests()) {
166
- let command = `--operation install --type ${this.type} --slug ${slug}`;
173
+ let command = `--appDir "${this.config.get('appDir')}" --operation "install" --type "${this.type}" --id "${slug}"`;
167
174
  if (version)
168
- command += ` --ver ${version}`;
175
+ command += ` --ver "${version}"`;
176
+ if (this.debug)
177
+ command += ` --log`;
169
178
  await runCliAsAdmin(command);
170
179
  return this.getPackage(slug)?.getVersion(versionNum);
171
180
  }
@@ -214,12 +223,21 @@ export class ManagerLocal extends Manager {
214
223
  if (this.type === RegistryType.Projects)
215
224
  formatDir = projectFormatDir;
216
225
  archiveExtract(filePath, dirSource);
217
- const filesMoved = filesMove(dirSource, this.typeDir, dirSub, formatDir);
218
- // Output json metadata into every directory a file was added to.
219
- filesMoved.forEach((fileMoved) => {
220
- const fileJson = path.join(path.dirname(fileMoved), 'index.json');
221
- fileCreateJson(fileJson, pkgVersion);
222
- });
226
+ // Move entire directory, maintaining the same folder structure.
227
+ if (pkgVersion.type === PluginType.Sampler) {
228
+ const dirTarget = path.join(this.typeDir, PluginType.Sampler, dirSub);
229
+ dirCreate(dirTarget);
230
+ dirMove(dirSource, dirTarget);
231
+ fileCreateJson(path.join(dirTarget, 'index.json'), pkgVersion);
232
+ }
233
+ else {
234
+ // Move only supported file extensions into their respective installation directories.
235
+ const filesMoved = filesMove(dirSource, this.typeDir, dirSub, formatDir);
236
+ filesMoved.forEach((fileMoved) => {
237
+ const fileJson = path.join(path.dirname(fileMoved), 'index.json');
238
+ fileCreateJson(fileJson, pkgVersion);
239
+ });
240
+ }
223
241
  }
224
242
  }
225
243
  pkgVersion.installed = true;
@@ -229,6 +247,7 @@ export class ManagerLocal extends Manager {
229
247
  // Get dependency package information from registry.
230
248
  const manager = new ManagerLocal(type, this.config.config);
231
249
  await manager.sync();
250
+ manager.scan();
232
251
  const pkg = manager.getPackage(slug);
233
252
  if (!pkg)
234
253
  return this.log(`Package ${slug} not found in registry`);
@@ -256,6 +275,7 @@ export class ManagerLocal extends Manager {
256
275
  const pkgFile = packageLoadFile(filePath);
257
276
  const manager = new ManagerLocal(type, this.config.config);
258
277
  await manager.sync();
278
+ manager.scan();
259
279
  for (const slug in pkgFile[type]) {
260
280
  await manager.install(slug, pkgFile[type][slug]);
261
281
  }
@@ -282,9 +302,11 @@ export class ManagerLocal extends Manager {
282
302
  return this.log(`Package ${slug} version ${versionNum} not installed`);
283
303
  // Elevate permissions if not running as admin.
284
304
  if (!isAdmin() && !isTests()) {
285
- let command = `--operation uninstall --type ${this.type} --slug ${slug}`;
305
+ let command = `--appDir "${this.config.get('appDir')}" --operation "install" --type "${this.type}" --id "${slug}"`;
286
306
  if (version)
287
- command += ` --ver ${version}`;
307
+ command += ` --ver "${version}"`;
308
+ if (this.debug)
309
+ command += ` --log`;
288
310
  await runCliAsAdmin(command);
289
311
  return this.getPackage(slug)?.getVersion(versionNum);
290
312
  }
@@ -318,6 +340,7 @@ export class ManagerLocal extends Manager {
318
340
  // Uninstall dependency.
319
341
  const manager = new ManagerLocal(type, this.config.config);
320
342
  await manager.sync();
343
+ manager.scan();
321
344
  await manager.uninstall(slug, version || pkgFile[type][slug]);
322
345
  // Remove dependency from local package file and save.
323
346
  if (!pkgFile[type])
@@ -332,6 +355,7 @@ export class ManagerLocal extends Manager {
332
355
  const pkgFile = packageLoadFile(filePath);
333
356
  const manager = new ManagerLocal(type, this.config.config);
334
357
  await manager.sync();
358
+ manager.scan();
335
359
  for (const slug in pkgFile[type]) {
336
360
  await manager.uninstall(slug, pkgFile[type][slug]);
337
361
  }
@@ -17,8 +17,8 @@ export class Package extends Base {
17
17
  this.version = this.latestVersion();
18
18
  }
19
19
  addVersion(num, version) {
20
- if (this.versions.has(num))
21
- return;
20
+ // For now allow package versions to be overwritten.
21
+ // if (this.versions.has(num)) return this.log(`Package ${version.name} version ${num} already exists`);
22
22
  const errors = packageErrors(version);
23
23
  const recs = packageRecommendations(version);
24
24
  const report = {
@@ -27,10 +27,8 @@ export class Package extends Base {
27
27
  };
28
28
  if (Object.keys(report).length > 0)
29
29
  this.reports.set(num, report);
30
- if (errors.length > 0) {
31
- this.log(errors);
32
- return;
33
- }
30
+ if (errors.length > 0)
31
+ return this.log(`Package ${version.name} version ${num} errors`, errors);
34
32
  this.versions.set(num, version);
35
33
  this.version = this.latestVersion();
36
34
  }
@@ -1,9 +1,11 @@
1
1
  import { RegistryType } from '../types/Registry.js';
2
2
  export interface Arguments {
3
+ appDir: string;
3
4
  operation: string;
4
5
  type: RegistryType;
5
6
  id: string;
6
- ver: string;
7
+ version?: string;
8
+ log?: boolean;
7
9
  }
8
10
  export declare function adminArguments(): Arguments;
9
11
  export declare function adminInit(): Promise<void>;
@@ -1,29 +1,52 @@
1
1
  // Run when Electron needs elevated privileges
2
2
  // npm run build && node ./build/helpers/admin.js --operation install --type plugins --id surge-synthesizer/surge
3
3
  // npm run build && node ./build/helpers/admin.js --operation uninstall --type plugins --id surge-synthesizer/surge
4
+ import { RegistryType } from '../types/Registry.js';
4
5
  import { ManagerLocal } from '../classes/ManagerLocal.js';
5
6
  import { dirApp } from './file.js';
6
- import { log } from './utils.js';
7
7
  export function adminArguments() {
8
- return {
9
- operation: process.argv[3],
10
- type: process.argv[5],
11
- id: process.argv[7],
12
- ver: process.argv[9],
8
+ const args = {
9
+ appDir: dirApp(),
10
+ operation: 'install',
11
+ type: RegistryType.Plugins,
12
+ id: 'surge-synthesizer/surge',
13
13
  };
14
+ for (let i = 0; i < process.argv.length; i++) {
15
+ const arg = process.argv[i];
16
+ if (arg === '--appDir') {
17
+ args.appDir = process.argv[i + 1];
18
+ }
19
+ else if (arg === '--operation') {
20
+ args.operation = process.argv[i + 1];
21
+ }
22
+ else if (arg === '--type') {
23
+ args.type = process.argv[i + 1];
24
+ }
25
+ else if (arg === '--id') {
26
+ args.id = process.argv[i + 1];
27
+ }
28
+ else if (arg === '--ver') {
29
+ args.version = process.argv[i + 1];
30
+ }
31
+ else if (arg === '--log') {
32
+ args.log = true;
33
+ }
34
+ }
35
+ return args;
14
36
  }
15
37
  export async function adminInit() {
16
- const argv = adminArguments();
17
- const manager = new ManagerLocal(argv.type, { appDir: dirApp() });
38
+ const args = adminArguments();
39
+ const manager = new ManagerLocal(args.type, { appDir: args.appDir });
40
+ if (args.log)
41
+ manager.logEnable();
42
+ manager.log('adminInit', args);
18
43
  await manager.sync();
19
- if (argv.operation === 'install') {
20
- await manager.install(argv.id, argv.ver);
21
- }
22
- else if (argv.operation === 'uninstall') {
23
- await manager.uninstall(argv.id, argv.ver);
44
+ manager.scan();
45
+ if (args.operation === 'install') {
46
+ await manager.install(args.id, args.version);
24
47
  }
25
- else {
26
- log('Missing --operation argument');
48
+ else if (args.operation === 'uninstall') {
49
+ await manager.uninstall(args.id, args.version);
27
50
  }
28
51
  }
29
52
  adminInit();
@@ -312,6 +312,7 @@ export function runCliAsAdmin(args) {
312
312
  const filename = fileURLToPath(import.meta.url).replace('src/', 'build/');
313
313
  const dirPathClean = dirname(filename).replace('app.asar', 'app.asar.unpacked');
314
314
  const script = path.join(dirPathClean, 'admin.js');
315
+ log(`node "${script}" ${args}`);
315
316
  sudoPrompt.exec(`node "${script}" ${args}`, { name: 'Open Audio Stack' }, (error, stdout, stderr) => {
316
317
  if (stdout) {
317
318
  log('runCliAsAdmin', stdout);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-audio-stack/core",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Open-source audio plugin management software",
5
5
  "type": "module",
6
6
  "main": "./build/index.js",