-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproject.ts
219 lines (205 loc) · 8.49 KB
/
project.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
import path from 'path';
import { configGet } from './config.js';
import { dirCreate, dirRead, fileAdd, fileDate, fileJsonCreate, fileReadJson, fileOpen } from './file.js';
import { pathGetDirectory, pathGetExt, pathGetFilename, pathGetWithoutExt, safeSlug } from './utils.js';
import { pluginInstall, pluginUninstall } from './plugin.js';
import { PluginVersionLocal, PluginValidationOptions } from './types/plugin.js';
import { ProjectType, ProjectTypes, ProjectVersion, ProjectVersionLocal } from './types/project.js';
import { question } from 'readline-sync';
function askQuestion(label: string, input: any, fallback: string) {
return question(`${label}: ($<defaultInput>) `, {
defaultInput: input || fallback,
});
}
export function projectCreate(projectPath: string, prompt: boolean = true): ProjectVersionLocal {
const project: ProjectVersionLocal = projectDefault() as ProjectVersionLocal;
const projectName: string = pathGetFilename(projectPath);
if (prompt) {
project.name = askQuestion('Name', project.name, projectName);
project.version = askQuestion('Version', project.version, '1.0.0');
project.description = askQuestion('Description', project.description, `${projectName} description`);
project.files.audio.name = askQuestion('Audio', project.files.audio.name, `${projectName}.wav`);
project.files.audio.url = path.join(projectPath, project.files.audio.name).replace(path.sep, '/');
project.files.image.name = askQuestion('Image', project.files.image.name, `${projectName}.png`);
project.files.image.url = path.join(projectPath, project.files.image.name).replace(path.sep, '/');
project.files.project.name = askQuestion('Main', project.files.project.name, `${projectName}.als`);
project.files.project.url = path.join(projectPath, project.files.project.name).replace(path.sep, '/');
}
project.id = safeSlug(pathGetDirectory(projectPath, path.sep).split(path.sep).join('/'));
project.path = projectPath;
project.status = 'installed';
const projectJsonPath: string = path.join(configGet('projectFolder'), `${projectName}.json`);
dirCreate(pathGetDirectory(projectJsonPath, path.sep));
return projectSave(projectJsonPath, project);
}
export function projectDefault(): ProjectVersion {
return {
id: 'studiorack-project',
author: 'studiorack-user',
homepage: 'https://studiorack.github.io/studiorack-site/',
name: 'StudioRack Project',
description: 'Created using StudioRack',
tags: ['StudioRack'],
version: '1.0.0',
license: 'cc0-1.0',
date: new Date().toISOString(),
type: {
name: 'Ableton',
ext: 'als',
},
files: {
audio: {
url: '',
size: 0,
},
image: {
url: '',
size: 0,
},
project: {
url: '',
size: 0,
},
},
plugins: {},
};
}
export function projectDirectory(project: ProjectVersion, depth?: number): string {
const projectPath: string = (project.id || '').replace(/\//g, path.sep);
const projectPaths: string[] = [configGet('projectFolder'), projectPath, project.version || ''];
if (depth) {
return projectPaths.slice(0, depth).join(path.sep);
}
return projectPaths.join(path.sep);
}
export async function projectGetLocal(id: string, version = ''): Promise<ProjectVersionLocal> {
const projects: ProjectVersionLocal[] = await projectsGetLocal();
return projects.filter((project: ProjectVersionLocal) => {
const matchVersion: boolean = version ? version === project.version : true;
return id === project.id && matchVersion;
})[0];
}
export async function projectsGetLocal(): Promise<ProjectVersionLocal[]> {
const projectTypes: ProjectTypes = configGet('projectTypes');
const projectExts: string[] = Object.keys(projectTypes).map((projectTypeKey: string) => {
return projectTypes[projectTypeKey as keyof ProjectTypes].ext;
});
const projectSearchPath: string = path.join(configGet('projectFolder'), '**', `*.{${projectExts.join(',')}}`);
const projectPaths: string[] = dirRead(projectSearchPath);
const projects: ProjectVersionLocal[] = [];
projectPaths.forEach((projectPath: string) => {
if (projectPath.includes('/Backup/')) return;
let project: any = fileReadJson(`${pathGetWithoutExt(projectPath)}.json`);
if (!project) {
project = projectValidate(projectPath, { files: true, json: true });
}
// Use installed path for id, repo and version (instead of autogenerated json)
const relativePath: string = projectPath.replace(configGet('projectFolder') + path.sep, '');
project.id = safeSlug(pathGetWithoutExt(relativePath).split(path.sep).join('/'));
// project.version = pathGetVersion(projectPath);
project.path = projectPath;
project.status = 'installed';
projects.push(project);
});
return projects;
}
export async function projectInstall(dir: string, id?: string, version?: string): Promise<ProjectVersionLocal> {
const project: ProjectVersionLocal = projectLoad(dir);
if (id) {
const pluginLocal: PluginVersionLocal = await pluginInstall(id, version);
if (pluginLocal) {
project.plugins[id] = pluginLocal.version || '';
}
} else {
for (const pluginId in project.plugins) {
await pluginInstall(pluginId, project.plugins[pluginId]);
}
}
return projectSave(dir, project);
}
export function projectLoad(dir: string): ProjectVersionLocal {
const projectJson: ProjectVersionLocal = fileReadJson(dir);
if (projectJson && !projectJson.plugins) {
projectJson.plugins = {};
}
return projectJson;
}
export function projectSave(dir: string, config: ProjectVersionLocal): ProjectVersionLocal {
fileJsonCreate(dir, config);
return config;
}
export async function projectStart(dir: string): Promise<Buffer> {
const project: ProjectVersionLocal = projectLoad(dir);
const filepath: string = project.files.project.name ? project.files.project.name : project.files.project.url;
const projectFilePath: string = path.join(pathGetDirectory(dir, path.sep), filepath);
return fileOpen(projectFilePath);
}
export function projectType(ext: string): ProjectType {
const projectTypes: ProjectTypes = configGet('projectTypes');
let type: ProjectType = {
name: 'Ableton',
ext: 'als',
};
Object.keys(projectTypes).forEach((key: string) => {
const currentType: ProjectType = projectTypes[key as keyof ProjectTypes];
if (currentType.ext === ext) {
type = currentType;
}
});
return type;
}
export async function projectUninstall(dir: string, id?: string, version?: string): Promise<ProjectVersionLocal> {
const project = projectLoad(dir);
if (id) {
let result = version;
if (!version) {
result = project.plugins[id];
}
const pluginLocal: PluginVersionLocal = await pluginUninstall(id, result);
if (pluginLocal) {
delete project.plugins[id];
}
} else {
for (const pluginId in project.plugins) {
await pluginUninstall(pluginId, project.plugins[pluginId]);
}
}
return projectSave(dir, project);
}
export function projectValidate(dir: string, options?: PluginValidationOptions): ProjectVersionLocal {
const relativePath: string = dir.replace(configGet('projectFolder') + path.sep, '');
const type: ProjectType = projectType(pathGetExt(dir));
let project: ProjectVersionLocal = projectDefault() as ProjectVersionLocal;
project.date = fileDate(dir).toISOString();
project.id = safeSlug(pathGetWithoutExt(relativePath).split(path.sep).join('/'));
project.name = pathGetFilename(relativePath, path.sep);
project.path = dir;
project.status = 'installed';
project.tags = [type.name];
project.type = type;
if (options && options.files) {
project = projectValidateFiles(dir, project);
}
if (options && options.json) {
const projectJsonPath: string = path.join(
pathGetDirectory(dir, path.sep),
`${pathGetFilename(dir, path.sep)}.json`,
);
fileJsonCreate(projectJsonPath, project);
}
return project;
}
export function projectValidateFiles(pathItem: string, json: any): any {
const ext: string = pathGetExt(pathItem);
const directory: string = pathGetDirectory(pathItem, path.sep);
const filename: string = pathGetFilename(pathItem, path.sep);
// Ensure files object exists
if (!json.files) {
json.files = {};
}
// Add audio, image and zip files
json = fileAdd(path.join(directory, `${filename}.wav`), `${filename}.wav`, 'audio', json);
json = fileAdd(path.join(directory, `${filename}.png`), `${filename}.png`, 'image', json);
json = fileAdd(path.join(directory, `${filename}.${ext}`), `${filename}.${ext}`, 'project', json);
return json;
}