@open-audio-stack/core 0.1.16 → 0.1.18

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,4 +1,5 @@
1
1
  import chalk from 'chalk';
2
+ import { logEnable, logDisable } from '../helpers/utils.js';
2
3
  export class Base {
3
4
  debug = false;
4
5
  log(...args) {
@@ -6,9 +7,11 @@ export class Base {
6
7
  console.log(...args);
7
8
  }
8
9
  logEnable() {
10
+ logEnable();
9
11
  return (this.debug = true);
10
12
  }
11
13
  logDisable() {
14
+ logDisable();
12
15
  return (this.debug = false);
13
16
  }
14
17
  logErrors(errors) {
@@ -4,7 +4,7 @@ import { RegistryType } from '../types/Registry.js';
4
4
  import { ConfigInterface } from '../types/Config.js';
5
5
  export declare class ManagerLocal extends Manager {
6
6
  protected typeDir: string;
7
- constructor(type: RegistryType, config: ConfigInterface);
7
+ constructor(type: RegistryType, config?: ConfigInterface);
8
8
  create(): Promise<void>;
9
9
  scan(ext?: string, installable?: boolean): void;
10
10
  export(dir: string, ext?: string): boolean;
@@ -154,11 +154,11 @@ export class ManagerLocal extends Manager {
154
154
  // Get package information from registry.
155
155
  const pkg = this.getPackage(slug);
156
156
  if (!pkg)
157
- return console.error(`Package ${slug} not found in registry`);
157
+ return this.log(`Package ${slug} not found in registry`);
158
158
  const versionNum = version || pkg.latestVersion();
159
159
  const pkgVersion = pkg?.getVersion(versionNum);
160
160
  if (!pkgVersion)
161
- return console.error(`Package ${slug} version ${versionNum} not found in registry`);
161
+ return this.log(`Package ${slug} version ${versionNum} not found in registry`);
162
162
  if (pkgVersion.installed)
163
163
  return pkgVersion;
164
164
  // Elevate permissions if not running as admin.
@@ -184,7 +184,7 @@ export class ManagerLocal extends Manager {
184
184
  // Filter for compatible files and download.
185
185
  const files = packageCompatibleFiles(pkgVersion, [getArchitecture()], [getSystem()], excludedFormats);
186
186
  if (!files.length)
187
- return console.error(`Error: No compatible files found for ${slug}`);
187
+ return this.log(`Error: No compatible files found for ${slug}`);
188
188
  for (const key in files) {
189
189
  // Download file to temporary directory if not already downloaded.
190
190
  const file = files[key];
@@ -196,7 +196,7 @@ export class ManagerLocal extends Manager {
196
196
  // Check file hash matches expected hash.
197
197
  const hash = await fileHash(filePath);
198
198
  if (hash !== file.sha256)
199
- return console.error(`Error: ${filePath} hash mismatch`);
199
+ return this.log(`Error: ${filePath} hash mismatch`);
200
200
  // If installer, run the installer headless (without the user interface).
201
201
  if (file.type === FileType.Installer) {
202
202
  if (isTests())
@@ -231,15 +231,15 @@ export class ManagerLocal extends Manager {
231
231
  await manager.sync();
232
232
  const pkg = manager.getPackage(slug);
233
233
  if (!pkg)
234
- return console.error(`Package ${slug} not found in registry`);
234
+ return this.log(`Package ${slug} not found in registry`);
235
235
  const versionNum = version || pkg.latestVersion();
236
236
  const pkgVersion = pkg?.getVersion(versionNum);
237
237
  if (!pkgVersion)
238
- return console.error(`Package ${slug} version ${versionNum} not found in registry`);
238
+ return this.log(`Package ${slug} version ${versionNum} not found in registry`);
239
239
  // Get local package file.
240
240
  const pkgFile = packageLoadFile(filePath);
241
241
  if (pkgFile[type] && pkgFile[type][slug] && pkgFile[type][slug] === versionNum) {
242
- return console.error(`Package ${slug} version ${versionNum} is already a dependency`);
242
+ return this.log(`Package ${slug} version ${versionNum} is already a dependency`);
243
243
  }
244
244
  // Install dependency.
245
245
  await manager.install(slug, version);
@@ -273,13 +273,13 @@ export class ManagerLocal extends Manager {
273
273
  // Get package information from registry.
274
274
  const pkg = this.getPackage(slug);
275
275
  if (!pkg)
276
- return console.error(`Package ${slug} not found in registry`);
276
+ return this.log(`Package ${slug} not found in registry`);
277
277
  const versionNum = version || pkg.latestVersion();
278
278
  const pkgVersion = pkg?.getVersion(versionNum);
279
279
  if (!pkgVersion)
280
- return console.error(`Package ${slug} version ${versionNum} not found in registry`);
280
+ return this.log(`Package ${slug} version ${versionNum} not found in registry`);
281
281
  if (!pkgVersion.installed)
282
- return console.error(`Package ${slug} version ${versionNum} not installed`);
282
+ return this.log(`Package ${slug} version ${versionNum} not installed`);
283
283
  // Elevate permissions if not running as admin.
284
284
  if (!isAdmin() && !isTests()) {
285
285
  let command = `--operation uninstall --type ${this.type} --slug ${slug}`;
@@ -312,9 +312,9 @@ export class ManagerLocal extends Manager {
312
312
  // Get local package file.
313
313
  const pkgFile = packageLoadFile(filePath);
314
314
  if (!pkgFile[type])
315
- return console.error(`Package ${type} is missing`);
315
+ return this.log(`Package ${type} is missing`);
316
316
  if (!pkgFile[type][slug])
317
- return console.error(`Package ${type} ${slug} is not a dependency`);
317
+ return this.log(`Package ${type} ${slug} is not a dependency`);
318
318
  // Uninstall dependency.
319
319
  const manager = new ManagerLocal(type, this.config.config);
320
320
  await manager.sync();
@@ -13,6 +13,7 @@ export declare class Package extends Base {
13
13
  };
14
14
  getVersion(num: string): PackageVersion | undefined;
15
15
  getVersionLatest(): PackageVersion | undefined;
16
+ getVersionOrLatest(num?: string): PackageVersion | undefined;
16
17
  latestVersion(): string;
17
18
  toJSON(): {
18
19
  slug: string;
@@ -10,7 +10,7 @@ export class Package extends Base {
10
10
  constructor(slug, versions) {
11
11
  super();
12
12
  if (!isValidSlug(slug))
13
- console.error('Invalid package slug', slug);
13
+ this.log('Invalid package slug', slug);
14
14
  this.reports = new Map();
15
15
  this.slug = slug;
16
16
  this.versions = versions ? new Map(Object.entries(versions)) : new Map();
@@ -28,7 +28,7 @@ export class Package extends Base {
28
28
  if (Object.keys(report).length > 0)
29
29
  this.reports.set(num, report);
30
30
  if (errors.length > 0) {
31
- console.error(errors);
31
+ this.log(errors);
32
32
  return;
33
33
  }
34
34
  this.versions.set(num, version);
@@ -49,6 +49,14 @@ export class Package extends Base {
49
49
  getVersionLatest() {
50
50
  return this.versions.get(this.latestVersion());
51
51
  }
52
+ getVersionOrLatest(num) {
53
+ if (num) {
54
+ const pkgVersion = this.getVersion(num);
55
+ if (pkgVersion)
56
+ return pkgVersion;
57
+ }
58
+ return this.getVersionLatest();
59
+ }
52
60
  latestVersion() {
53
61
  return Array.from(this.versions.keys()).sort(semver.rcompare)[0] || '0.0.0';
54
62
  }
@@ -3,6 +3,7 @@
3
3
  // npm run build && node ./build/helpers/admin.js --operation uninstall --type plugins --id surge-synthesizer/surge
4
4
  import { ManagerLocal } from '../classes/ManagerLocal.js';
5
5
  import { dirApp } from './file.js';
6
+ import { log } from './utils.js';
6
7
  export function adminArguments() {
7
8
  return {
8
9
  operation: process.argv[3],
@@ -22,7 +23,7 @@ export async function adminInit() {
22
23
  await manager.uninstall(argv.id, argv.ver);
23
24
  }
24
25
  else {
25
- console.error('Missing --operation argument');
26
+ log('Missing --operation argument');
26
27
  }
27
28
  }
28
29
  adminInit();
@@ -1,12 +1,13 @@
1
+ import { log } from './utils.js';
1
2
  export async function apiBuffer(url) {
2
- console.log('⤓', url);
3
+ log('⤓', url);
3
4
  return fetch(url).then((res) => res.arrayBuffer());
4
5
  }
5
6
  export async function apiJson(url) {
6
- console.log('⤓', url);
7
+ log('⤓', url);
7
8
  return fetch(url).then((res) => res.json());
8
9
  }
9
10
  export async function apiText(url) {
10
- console.log('⤓', url);
11
+ log('⤓', url);
11
12
  return fetch(url).then((res) => res.text());
12
13
  }
@@ -15,8 +15,9 @@ import { SystemType } from '../types/SystemType.js';
15
15
  import { fileURLToPath } from 'url';
16
16
  import sudoPrompt from '@vscode/sudo-prompt';
17
17
  import { getSystem } from './utilsLocal.js';
18
+ import { log } from './utils.js';
18
19
  export async function archiveExtract(filePath, dirPath) {
19
- console.log('⎋', dirPath);
20
+ log('⎋', dirPath);
20
21
  const ext = path.extname(filePath).trim().toLowerCase();
21
22
  if (ext === '.zip') {
22
23
  const zip = new AdmZip(filePath);
@@ -47,7 +48,7 @@ export function dirContains(parentDir, childDir) {
47
48
  }
48
49
  export function dirCreate(dir) {
49
50
  if (!dirExists(dir)) {
50
- console.log('+', dir);
51
+ log('+', dir);
51
52
  mkdirSync(dir, { recursive: true });
52
53
  return dir;
53
54
  }
@@ -55,7 +56,7 @@ export function dirCreate(dir) {
55
56
  }
56
57
  export function dirDelete(dir) {
57
58
  if (dirExists(dir)) {
58
- console.log('-', dir);
59
+ log('-', dir);
59
60
  return rmSync(dir, { recursive: true });
60
61
  }
61
62
  return false;
@@ -72,8 +73,8 @@ export function dirIs(dir) {
72
73
  }
73
74
  export function dirMove(dir, dirNew) {
74
75
  if (dirExists(dir)) {
75
- console.log('-', dir);
76
- console.log('+', dirNew);
76
+ log('-', dir);
77
+ log('+', dirNew);
77
78
  return moveSync(dir, dirNew, { overwrite: true });
78
79
  }
79
80
  return false;
@@ -88,7 +89,7 @@ export function dirOpen(dir) {
88
89
  command = 'open';
89
90
  else
90
91
  command = 'xdg-open';
91
- console.log('⎋', `${command} "${dir}"`);
92
+ log('⎋', `${command} "${dir}"`);
92
93
  return execSync(`${command} "${dir}"`);
93
94
  }
94
95
  export function dirPackage(pkg) {
@@ -120,7 +121,7 @@ export function dirProjects() {
120
121
  return path.join(os.homedir(), 'Documents', 'Audio');
121
122
  }
122
123
  export function dirRead(dir, options) {
123
- console.log('⌕', dir);
124
+ log('⌕', dir);
124
125
  // Glob now expects forward slashes on Windows
125
126
  // Convert backslashes from path.join() to forwardslashes
126
127
  if (getSystem() === SystemType.Win) {
@@ -135,7 +136,7 @@ export function dirRename(dir, dirNew) {
135
136
  return false;
136
137
  }
137
138
  export function fileCreate(filePath, data) {
138
- console.log('+', filePath);
139
+ log('+', filePath);
139
140
  return writeFileSync(filePath, data);
140
141
  }
141
142
  export function fileCreateJson(filePath, data) {
@@ -149,7 +150,7 @@ export function fileDate(filePath) {
149
150
  }
150
151
  export function fileDelete(filePath) {
151
152
  if (fileExists(filePath)) {
152
- console.log('-', filePath);
153
+ log('-', filePath);
153
154
  return unlinkSync(filePath);
154
155
  }
155
156
  return false;
@@ -161,7 +162,7 @@ export function fileExists(filePath) {
161
162
  return existsSync(filePath);
162
163
  }
163
164
  export async function fileHash(filePath, algorithm = 'sha256') {
164
- console.log('⎋', filePath);
165
+ log('⎋', filePath);
165
166
  const input = createReadStream(filePath);
166
167
  const hash = createHash(algorithm);
167
168
  await stream.pipeline(input, hash);
@@ -194,13 +195,13 @@ export function fileInstall(filePath) {
194
195
  default:
195
196
  throw new Error(`Unsupported file format: ${ext}`);
196
197
  }
197
- console.log('⎋', command);
198
+ log('⎋', command);
198
199
  return execSync(command, { stdio: 'inherit' });
199
200
  }
200
201
  export function fileMove(filePath, newPath) {
201
202
  if (fileExists(filePath)) {
202
- console.log('-', filePath);
203
- console.log('+', newPath);
203
+ log('-', filePath);
204
+ log('+', newPath);
204
205
  return moveSync(filePath, newPath, { overwrite: true });
205
206
  }
206
207
  return false;
@@ -217,10 +218,10 @@ export function filesMove(dirSource, dirTarget, dirSub, formatDir) {
217
218
  const fileExtTarget = formatDir[fileExt];
218
219
  // If this is not a supported file format, then ignore.
219
220
  if (fileExtTarget === undefined)
220
- return console.error(`${fileSource} - ${fileExt} not mapped to a installation folder, skipping.`);
221
+ return log(`${fileSource} - ${fileExt} not mapped to a installation folder, skipping.`);
221
222
  const fileTarget = path.join(dirTarget, fileExtTarget, dirSub, path.basename(fileSource));
222
223
  if (fileExists(fileTarget))
223
- return console.error(`${fileSource} - ${fileTarget} already exists, skipping.`);
224
+ return log(`${fileSource} - ${fileTarget} already exists, skipping.`);
224
225
  dirCreate(path.dirname(fileTarget));
225
226
  fileMove(fileSource, fileTarget);
226
227
  filesMoved.push(fileTarget);
@@ -237,22 +238,22 @@ export function fileOpen(filePath) {
237
238
  command = 'open';
238
239
  else
239
240
  command = 'xdg-open';
240
- console.log('⎋', `${command} "${filePath}"`);
241
+ log('⎋', `${command} "${filePath}"`);
241
242
  return execSync(`${command} "${filePath}"`);
242
243
  }
243
244
  export function fileRead(filePath) {
244
- console.log('⎋', filePath);
245
+ log('⎋', filePath);
245
246
  return readFileSync(filePath, 'utf8');
246
247
  }
247
248
  export function fileReadJson(filePath) {
248
249
  if (fileExists(filePath)) {
249
- console.log('⎋', filePath);
250
+ log('⎋', filePath);
250
251
  return JSON.parse(readFileSync(filePath, 'utf8').toString());
251
252
  }
252
253
  return false;
253
254
  }
254
255
  export function fileReadString(filePath) {
255
- console.log('⎋', filePath);
256
+ log('⎋', filePath);
256
257
  return readFileSync(filePath, 'utf8').toString();
257
258
  }
258
259
  export function fileReadYaml(filePath) {
@@ -313,10 +314,10 @@ export function runCliAsAdmin(args) {
313
314
  const script = path.join(dirPathClean, 'admin.js');
314
315
  sudoPrompt.exec(`node "${script}" ${args}`, { name: 'Open Audio Stack' }, (error, stdout, stderr) => {
315
316
  if (stdout) {
316
- console.log('runCliAsAdmin', stdout);
317
+ log('runCliAsAdmin', stdout);
317
318
  }
318
319
  if (stderr) {
319
- console.log('runCliAsAdmin', stderr);
320
+ log('runCliAsAdmin', stderr);
320
321
  }
321
322
  if (error) {
322
323
  reject(error);
@@ -334,7 +335,7 @@ export function zipCreate(filesPath, zipPath) {
334
335
  const zip = new AdmZip();
335
336
  const pathList = dirRead(filesPath);
336
337
  pathList.forEach(pathItem => {
337
- console.log('⎋', pathItem);
338
+ log('⎋', pathItem);
338
339
  try {
339
340
  if (dirIs(pathItem)) {
340
341
  zip.addLocalFolder(pathItem, path.basename(pathItem));
@@ -344,9 +345,9 @@ export function zipCreate(filesPath, zipPath) {
344
345
  }
345
346
  }
346
347
  catch (error) {
347
- console.error(error);
348
+ log(error);
348
349
  }
349
350
  });
350
- console.log('+', zipPath);
351
+ log('+', zipPath);
351
352
  return zip.writeZip(zipPath);
352
353
  }
@@ -87,7 +87,6 @@ export declare const PackageTypeObj: {
87
87
  Effect: PluginType.Effect;
88
88
  Generator: PluginType.Generator;
89
89
  Instrument: PluginType.Instrument;
90
- Preset: PluginType.Preset;
91
90
  Sampler: PluginType.Sampler;
92
91
  Tool: PluginType.Tool;
93
92
  };
@@ -160,7 +159,6 @@ export declare const PackageVersionValidator: z.ZodObject<{
160
159
  Effect: PluginType.Effect;
161
160
  Generator: PluginType.Generator;
162
161
  Instrument: PluginType.Instrument;
163
- Preset: PluginType.Preset;
164
162
  Sampler: PluginType.Sampler;
165
163
  Tool: PluginType.Tool;
166
164
  }>;
@@ -1,18 +1,18 @@
1
1
  import path from 'path';
2
2
  import { fileCreateJson, fileReadJson } from './file.js';
3
3
  import { Package } from '../classes/Package.js';
4
- import { pathGetSlug, pathGetVersion } from './utils.js';
4
+ import { log, pathGetSlug, pathGetVersion } from './utils.js';
5
5
  export function packageLoadFile(filePath) {
6
6
  // Read the file path and parse as json.
7
7
  if (!filePath)
8
8
  filePath = path.join('.', 'index.json');
9
9
  const pkgFile = fileReadJson(filePath);
10
10
  if (!pkgFile)
11
- console.error(filePath, `not a valid json file`);
11
+ log(filePath, `not a valid json file`);
12
12
  // Validate package json file structure, fields and values.
13
13
  const pkg = new Package(pathGetSlug(filePath));
14
14
  pkg.addVersion(pathGetVersion(filePath), pkgFile);
15
- console.log(JSON.stringify(pkg.getReport()));
15
+ log(JSON.stringify(pkg.getReport()));
16
16
  return pkgFile;
17
17
  }
18
18
  export function packageSaveFile(pkgFile, filePath) {
@@ -1,4 +1,7 @@
1
1
  export declare function inputGetParts(input: string): string[];
2
+ export declare function log(...args: any): void;
3
+ export declare function logEnable(): boolean;
4
+ export declare function logDisable(): boolean;
2
5
  export declare function pathGetDirectory(path: string, sep?: string): string;
3
6
  export declare function pathGetExt(path: string, sep?: string): string;
4
7
  export declare function pathGetFilename(path: string, sep?: string): string;
@@ -1,9 +1,20 @@
1
1
  import * as semver from 'semver';
2
2
  import slugify from 'slugify';
3
+ let DEBUG = false;
3
4
  const URLSAFE_REGEX = /[^\w\s$*_+~.()'"!\-:@/]+/g;
4
5
  export function inputGetParts(input) {
5
6
  return input.split('@');
6
7
  }
8
+ export function log(...args) {
9
+ if (DEBUG)
10
+ console.log(...args);
11
+ }
12
+ export function logEnable() {
13
+ return (DEBUG = true);
14
+ }
15
+ export function logDisable() {
16
+ return (DEBUG = false);
17
+ }
7
18
  export function pathGetDirectory(path, sep = '/') {
8
19
  return path.substring(0, path.lastIndexOf(sep));
9
20
  }
@@ -2,7 +2,6 @@ export declare enum PluginType {
2
2
  Effect = "effect",
3
3
  Generator = "generator",
4
4
  Instrument = "instrument",
5
- Preset = "preset",
6
5
  Sampler = "sampler",
7
6
  Tool = "tool"
8
7
  }
@@ -3,7 +3,6 @@ export var PluginType;
3
3
  PluginType["Effect"] = "effect";
4
4
  PluginType["Generator"] = "generator";
5
5
  PluginType["Instrument"] = "instrument";
6
- PluginType["Preset"] = "preset";
7
6
  PluginType["Sampler"] = "sampler";
8
7
  PluginType["Tool"] = "tool";
9
8
  })(PluginType || (PluginType = {}));
@@ -23,11 +22,6 @@ export const pluginTypes = [
23
22
  value: PluginType.Instrument,
24
23
  name: 'Instrument',
25
24
  },
26
- {
27
- description: 'Preset containing predefined settings for an instrument or effect.',
28
- value: PluginType.Preset,
29
- name: 'Preset',
30
- },
31
25
  {
32
26
  description: 'Sample playback based on audio or midi input.',
33
27
  value: PluginType.Sampler,
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@open-audio-stack/core",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Open-source audio plugin management software",
5
5
  "type": "module",
6
6
  "main": "./build/index.js",
7
7
  "exports": {
8
+ "import": "./build/index.js",
8
9
  "node": "./build/index.js",
9
10
  "default": "./build/index-browser.js"
10
11
  },
@@ -43,14 +44,14 @@
43
44
  "@types/js-yaml": "^4.0.9",
44
45
  "@types/node": "^22.7.8",
45
46
  "@types/semver": "^7.5.8",
46
- "@vitest/coverage-v8": "^2.1.3",
47
+ "@vitest/coverage-v8": "^3.0.5",
47
48
  "eslint": "^9.12.0",
48
49
  "globals": "^15.2.0",
49
50
  "prettier": "^3.2.5",
50
- "tsx": "^4.10.1",
51
+ "tsx": "^4.19.2",
51
52
  "typescript": "^5.6.3",
52
53
  "typescript-eslint": "^8.9.0",
53
- "vitest": "^2.1.3"
54
+ "vitest": "^3.0.5"
54
55
  },
55
56
  "dependencies": {
56
57
  "@vscode/sudo-prompt": "^9.3.1",