sandstone-cli 0.6.6 → 1.0.1
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/.github/FUNDING.yml +4 -0
- package/.github/workflows/npm-publish.yml +27 -0
- package/LICENSE +21 -0
- package/README.md +2 -191
- package/lib/build/{buildProject.d.ts → index.d.ts} +14 -14
- package/lib/build/{buildProject.js → index.js} +93 -204
- package/lib/commands/build.d.ts +18 -29
- package/lib/commands/build.js +11 -31
- package/lib/commands/create.d.ts +8 -24
- package/lib/commands/create.js +150 -166
- package/lib/commands/index.d.ts +3 -0
- package/lib/commands/index.js +4 -0
- package/lib/commands/watch.d.ts +16 -29
- package/lib/commands/watch.js +61 -106
- package/lib/index.d.ts +2 -1
- package/lib/index.js +77 -5
- package/lib/utils.d.ts +3 -3
- package/lib/utils.js +37 -48
- package/package.json +49 -84
- package/src/build/index.ts +572 -0
- package/src/commands/build.ts +38 -0
- package/src/commands/create.ts +225 -0
- package/src/commands/index.ts +4 -0
- package/src/commands/watch.ts +99 -0
- package/src/index.ts +93 -0
- package/src/utils.ts +135 -0
- package/tsconfig.json +18 -0
- package/bin/run +0 -6
- package/bin/run.cmd +0 -3
- package/lib/build/graph.d.ts +0 -49
- package/lib/build/graph.js +0 -197
- package/lib/commands/update.d.ts +0 -15
- package/lib/commands/update.js +0 -126
- package/lib/onUpdate.d.ts +0 -2
- package/lib/onUpdate.js +0 -9
- package/oclif.manifest.json +0 -1
|
@@ -1,49 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
-
};
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.buildProject = void 0;
|
|
26
|
-
const path_1 = __importDefault(require("path"));
|
|
27
|
-
const os = __importStar(require("os"));
|
|
28
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
29
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
30
|
-
const pretty_error_1 = __importDefault(require("pretty-error"));
|
|
31
|
-
const klaw_1 = __importDefault(require("klaw"));
|
|
32
|
-
const madge_1 = __importDefault(require("madge"));
|
|
33
|
-
const graph_1 = require("./graph");
|
|
34
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
35
|
-
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
36
|
-
const delete_empty_1 = __importDefault(require("delete-empty"));
|
|
37
|
-
const pe = new pretty_error_1.default();
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import crypto from 'crypto';
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import PrettyError from 'pretty-error';
|
|
6
|
+
import walk from 'klaw';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import AdmZip from 'adm-zip';
|
|
9
|
+
import deleteEmpty from 'delete-empty';
|
|
10
|
+
const pe = new PrettyError();
|
|
38
11
|
// Return the hash of a string
|
|
39
12
|
function hash(stringToHash) {
|
|
40
|
-
return
|
|
13
|
+
return crypto.createHash('md5').update(stringToHash).digest('hex');
|
|
41
14
|
}
|
|
42
15
|
// Recursively create a directory, without failing if it already exists
|
|
43
16
|
async function mkDir(dirPath) {
|
|
44
17
|
try {
|
|
45
18
|
await new Promise((resolve, reject) => {
|
|
46
|
-
|
|
19
|
+
fs.mkdir(dirPath, { recursive: true }, (err) => {
|
|
47
20
|
if (err)
|
|
48
21
|
reject(err);
|
|
49
22
|
resolve();
|
|
@@ -55,32 +28,6 @@ async function mkDir(dirPath) {
|
|
|
55
28
|
}
|
|
56
29
|
}
|
|
57
30
|
let cache;
|
|
58
|
-
const dependenciesCache = new graph_1.DependencyGraph({});
|
|
59
|
-
const fileResources = new Map();
|
|
60
|
-
function getNewModules(dependenciesGraph, rawFiles, projectFolder) {
|
|
61
|
-
const rawFilesPath = rawFiles.map(({ path }) => path);
|
|
62
|
-
// Get only the new modules
|
|
63
|
-
const newModules = [...dependenciesGraph.nodes.values()].filter((node) => rawFilesPath.includes(path_1.default.join(projectFolder, node.name)));
|
|
64
|
-
// Get their dependants, as a set to avoid duplicates
|
|
65
|
-
const newModulesDependencies = new Set(newModules.flatMap((node) => [...node.getDependsOn({ recursive: true, includeSelf: true })]));
|
|
66
|
-
// Sort them by number of dependencies, and return them
|
|
67
|
-
return [...newModulesDependencies].sort((a, b) => a.getDependencies({ recursive: true }).size - b.getDependencies({ recursive: true }).size);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Returns a set of all values present in set1 and not present in set2.
|
|
71
|
-
*/
|
|
72
|
-
function diffSet(set1, set2) {
|
|
73
|
-
return [...set1].filter((element) => !set2.has(element));
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Returns a map of all key/value present in map1 and not present in map2.
|
|
77
|
-
*/
|
|
78
|
-
function diffMap(map1, map2) {
|
|
79
|
-
return new Map([...map1.entries()].filter(([key, value]) => !map2.has(key)));
|
|
80
|
-
}
|
|
81
|
-
function diffResources(tree1, tree2) {
|
|
82
|
-
return diffSet(tree1, tree2);
|
|
83
|
-
}
|
|
84
31
|
/**
|
|
85
32
|
*
|
|
86
33
|
* @param worldName The name of the world
|
|
@@ -93,12 +40,12 @@ async function getClientWorldPath(worldName, minecraftPath = undefined) {
|
|
|
93
40
|
mcPath = minecraftPath;
|
|
94
41
|
}
|
|
95
42
|
else {
|
|
96
|
-
mcPath = await getClientPath();
|
|
43
|
+
mcPath = (await getClientPath());
|
|
97
44
|
}
|
|
98
|
-
const savesPath =
|
|
99
|
-
const worldPath =
|
|
100
|
-
if (!
|
|
101
|
-
const existingWorlds = (await
|
|
45
|
+
const savesPath = path.join(mcPath, 'saves');
|
|
46
|
+
const worldPath = path.join(savesPath, worldName);
|
|
47
|
+
if (!fs.existsSync(worldPath)) {
|
|
48
|
+
const existingWorlds = (await fs.readdir(savesPath, { withFileTypes: true })).filter((f) => f.isDirectory).map((f) => f.name);
|
|
102
49
|
throw new Error(`Unable to locate the "${worldPath}" folder. Word ${worldName} does not exists. List of existing worlds: ${JSON.stringify(existingWorlds, null, 2)}`);
|
|
103
50
|
}
|
|
104
51
|
return worldPath;
|
|
@@ -110,17 +57,21 @@ async function getClientPath() {
|
|
|
110
57
|
function getMCPath() {
|
|
111
58
|
switch (os.platform()) {
|
|
112
59
|
case 'win32':
|
|
113
|
-
return
|
|
60
|
+
return path.join(os.homedir(), 'AppData/Roaming/.minecraft');
|
|
114
61
|
case 'darwin':
|
|
115
|
-
return
|
|
62
|
+
return path.join(os.homedir(), 'Library/Application Support/minecraft');
|
|
116
63
|
case 'linux':
|
|
117
64
|
default:
|
|
118
|
-
return
|
|
65
|
+
return path.join(os.homedir(), '.minecraft');
|
|
119
66
|
}
|
|
120
67
|
}
|
|
121
68
|
const mcPath = getMCPath();
|
|
122
|
-
|
|
123
|
-
|
|
69
|
+
try {
|
|
70
|
+
await fs.stat(mcPath);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.warn('Unable to locate the .minecraft folder. Will not be able to export to client.');
|
|
74
|
+
return undefined;
|
|
124
75
|
}
|
|
125
76
|
return mcPath;
|
|
126
77
|
}
|
|
@@ -131,18 +82,20 @@ async function getClientPath() {
|
|
|
131
82
|
*
|
|
132
83
|
* @param projectFolder The folder of the project. It needs a sandstone.config.ts, and it or one of its parent needs a package.json.
|
|
133
84
|
*/
|
|
134
|
-
async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandstoneConfigFolder }
|
|
85
|
+
async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandstoneConfigFolder }) {
|
|
135
86
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
136
|
-
const sandstoneLocation = path_1.default.join(rootFolder, 'node_modules/sandstone/');
|
|
137
87
|
// First, read sandstone.config.ts to get all properties
|
|
138
|
-
const sandstoneConfig =
|
|
139
|
-
const {
|
|
140
|
-
|
|
88
|
+
const sandstoneConfig = (await import(path.join(sandstoneConfigFolder, 'sandstone.config.ts'))).default;
|
|
89
|
+
const { scripts } = sandstoneConfig;
|
|
90
|
+
let { saveOptions } = sandstoneConfig;
|
|
91
|
+
if (saveOptions === undefined)
|
|
92
|
+
saveOptions = {};
|
|
93
|
+
const outputFolder = path.join(rootFolder, '.sandstone', 'output');
|
|
141
94
|
/// OPTIONS ///
|
|
142
95
|
const clientPath = !cliOptions.production ? (cliOptions.clientPath || saveOptions.clientPath || await getClientPath()) : undefined;
|
|
143
96
|
const server = !cliOptions.production && (cliOptions.serverPath || saveOptions.serverPath || cliOptions.ssh || saveOptions.ssh) ? await (async () => {
|
|
144
97
|
if (cliOptions.ssh || saveOptions.ssh) {
|
|
145
|
-
const sshOptions = JSON.stringify(await
|
|
98
|
+
const sshOptions = JSON.stringify(await fs.readFile(cliOptions.ssh || saveOptions.ssh, 'utf8'));
|
|
146
99
|
// TODO: implement SFTP
|
|
147
100
|
return {
|
|
148
101
|
readFile: async (relativePath, encoding = 'utf8') => { },
|
|
@@ -152,16 +105,16 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
152
105
|
}
|
|
153
106
|
const serverPath = cliOptions.serverPath || saveOptions.serverPath;
|
|
154
107
|
return {
|
|
155
|
-
readFile: async (relativePath, encoding = 'utf8') => await
|
|
108
|
+
readFile: async (relativePath, encoding = 'utf8') => await fs.readFile(path.join(serverPath, relativePath), encoding),
|
|
156
109
|
writeFile: async (relativePath, contents) => {
|
|
157
110
|
if (contents === undefined) {
|
|
158
|
-
await
|
|
111
|
+
await fs.unlink(path.join(serverPath, relativePath));
|
|
159
112
|
}
|
|
160
113
|
else {
|
|
161
|
-
await
|
|
114
|
+
await fs.writeFile(path.join(serverPath, relativePath), contents);
|
|
162
115
|
}
|
|
163
116
|
},
|
|
164
|
-
remove: async (relativePath) => await
|
|
117
|
+
remove: async (relativePath) => await fs.remove(path.join(serverPath, relativePath))
|
|
165
118
|
};
|
|
166
119
|
})() : undefined;
|
|
167
120
|
let worldName = cliOptions.world || saveOptions.world;
|
|
@@ -211,80 +164,19 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
211
164
|
// The configuration is ready.
|
|
212
165
|
// Now, let's run the beforeAll script
|
|
213
166
|
await ((_b = scripts === null || scripts === void 0 ? void 0 : scripts.beforeAll) === null || _b === void 0 ? void 0 : _b.call(scripts));
|
|
214
|
-
// Finally, let's import
|
|
167
|
+
// Finally, let's import from the index.
|
|
215
168
|
let error = false;
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 1. Update dependency graphs
|
|
224
|
-
* 2. Delete all cache & resources for files dependent from the changed files
|
|
225
|
-
* 3. Import all changed files, & their dependents
|
|
226
|
-
* 4. Save only newly created resources
|
|
227
|
-
*/
|
|
228
|
-
const graph = await (0, madge_1.default)(rawFiles.map(f => f.path).filter(f => !f.endsWith('.json')), {
|
|
229
|
-
fileExtensions: ['.ts', '.cts', '.mts', '.tsx', '.js', '.jsx', '.cjs', '.mjs', '.json'],
|
|
230
|
-
includeNpm: false,
|
|
231
|
-
baseDir: absProjectFolder,
|
|
232
|
-
detectiveOptions: {
|
|
233
|
-
es6: {
|
|
234
|
-
skipTypeImports: true,
|
|
235
|
-
},
|
|
236
|
-
ts: {
|
|
237
|
-
skipTypeImports: true,
|
|
238
|
-
},
|
|
239
|
-
},
|
|
240
|
-
});
|
|
241
|
-
// This dependencies graph is only partial.
|
|
242
|
-
const dependenciesGraph = new graph_1.DependencyGraph(graph.obj());
|
|
243
|
-
// Update the global dependency graph by merging it with the new one.
|
|
244
|
-
dependenciesCache.merge(dependenciesGraph);
|
|
245
|
-
// Transform resolved dependents into a flat list of files, and sort them by their number of dependencies
|
|
246
|
-
const newModules = getNewModules(dependenciesCache, changedFilesPaths !== null && changedFilesPaths !== void 0 ? changedFilesPaths : rawFiles, absProjectFolder);
|
|
247
|
-
const { sandstonePack } = require(sandstoneLocation);
|
|
248
|
-
// If files changed, we need to clean the cache & delete the related resources
|
|
249
|
-
if (changedFiles) {
|
|
250
|
-
for (const node of newModules) {
|
|
251
|
-
// For each changed file, we need to reset the require cache
|
|
252
|
-
delete require.cache[path_1.default.join(absProjectFolder, node.name)];
|
|
253
|
-
// Then we need to delete all resources the file created
|
|
254
|
-
const oldResources = fileResources.get(node.name);
|
|
255
|
-
if (oldResources) {
|
|
256
|
-
for (const resource of oldResources.resources) {
|
|
257
|
-
sandstonePack.core.deleteResource(resource.path, resource.resourceType);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
169
|
+
let sandstonePack;
|
|
170
|
+
const filePath = path.join(absProjectFolder, 'index.ts');
|
|
171
|
+
try {
|
|
172
|
+
// Sometimes, a file might not exist because it has been deleted.
|
|
173
|
+
if (await fs.pathExists(filePath)) {
|
|
174
|
+
sandstonePack = (await import(filePath)).default;
|
|
260
175
|
}
|
|
261
176
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const currentResources = {
|
|
266
|
-
resources: new Set([...sandstonePack.core.resourceNodes]),
|
|
267
|
-
objectives: new Set([...sandstonePack.objectives.entries()])
|
|
268
|
-
};
|
|
269
|
-
// We have a module, let's require it!
|
|
270
|
-
const filePath = path_1.default.resolve(modulePath);
|
|
271
|
-
try {
|
|
272
|
-
// Sometimes, a file might not exist because it has been deleted.
|
|
273
|
-
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
274
|
-
require(filePath);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
catch (e) {
|
|
278
|
-
logError(e, node.name);
|
|
279
|
-
error = true;
|
|
280
|
-
}
|
|
281
|
-
// Now, find the resources that were added by this file & store them.
|
|
282
|
-
// This will be used if those files are changed later.
|
|
283
|
-
const newResources = {
|
|
284
|
-
resources: diffResources(sandstonePack.core.resourceNodes, currentResources.resources),
|
|
285
|
-
objectives: diffSet(sandstonePack.objectives, currentResources.objectives),
|
|
286
|
-
};
|
|
287
|
-
fileResources.set(node.name, newResources);
|
|
177
|
+
catch (e) {
|
|
178
|
+
logError(e, absProjectFolder);
|
|
179
|
+
error = true;
|
|
288
180
|
}
|
|
289
181
|
if (error) {
|
|
290
182
|
return;
|
|
@@ -293,11 +185,11 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
293
185
|
// Setup the cache if it doesn't exist.
|
|
294
186
|
// This cache is here to avoid writing files on disk when they did not change.
|
|
295
187
|
const newCache = {};
|
|
296
|
-
const cacheFile =
|
|
188
|
+
const cacheFile = path.join(rootFolder, '.sandstone', 'cache.json');
|
|
297
189
|
if (cache === undefined) {
|
|
298
190
|
let oldCache;
|
|
299
191
|
try {
|
|
300
|
-
const fileRead = await
|
|
192
|
+
const fileRead = await fs.readFile(cacheFile, 'utf8');
|
|
301
193
|
if (fileRead) {
|
|
302
194
|
oldCache = JSON.parse(fileRead);
|
|
303
195
|
}
|
|
@@ -349,23 +241,23 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
349
241
|
return;
|
|
350
242
|
}
|
|
351
243
|
// Not in cache: write to disk
|
|
352
|
-
const realPath =
|
|
353
|
-
await mkDir(
|
|
354
|
-
return await
|
|
244
|
+
const realPath = path.join(outputFolder, relativePath);
|
|
245
|
+
await mkDir(path.dirname(realPath));
|
|
246
|
+
return await fs.writeFile(realPath, content);
|
|
355
247
|
}
|
|
356
248
|
})
|
|
357
249
|
});
|
|
358
250
|
async function handleResources(packType) {
|
|
359
|
-
const working =
|
|
251
|
+
const working = path.join(rootFolder, 'resources', packType);
|
|
360
252
|
let exists = false;
|
|
361
253
|
try {
|
|
362
|
-
await
|
|
254
|
+
await fs.access(working);
|
|
363
255
|
exists = true;
|
|
364
256
|
}
|
|
365
257
|
catch (e) { }
|
|
366
258
|
if (exists) {
|
|
367
|
-
for await (const file of (
|
|
368
|
-
const relativePath =
|
|
259
|
+
for await (const file of walk(path.join(rootFolder, 'resources', packType), { filter: (_path) => {
|
|
260
|
+
const relativePath = path.join(packType, _path.split(working)[1]);
|
|
369
261
|
let pathPass = true;
|
|
370
262
|
if (fileExclusions && fileExclusions.existing) {
|
|
371
263
|
for (const exclude of fileExclusions.existing) {
|
|
@@ -374,9 +266,9 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
374
266
|
}
|
|
375
267
|
return pathPass;
|
|
376
268
|
} })) {
|
|
377
|
-
const relativePath =
|
|
269
|
+
const relativePath = path.join(packType, file.path.split(working)[1]);
|
|
378
270
|
try {
|
|
379
|
-
let content = await
|
|
271
|
+
let content = await fs.readFile(file.path);
|
|
380
272
|
if (fileHandlers) {
|
|
381
273
|
for (const handler of fileHandlers) {
|
|
382
274
|
if (handler.path.test(relativePath)) {
|
|
@@ -390,9 +282,9 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
390
282
|
newCache[relativePath] = hashValue;
|
|
391
283
|
if (cache[relativePath] !== hashValue) {
|
|
392
284
|
// Not in cache: write to disk
|
|
393
|
-
const realPath =
|
|
394
|
-
await mkDir(
|
|
395
|
-
await
|
|
285
|
+
const realPath = path.join(outputFolder, relativePath);
|
|
286
|
+
await mkDir(path.dirname(realPath));
|
|
287
|
+
await fs.writeFile(realPath, content);
|
|
396
288
|
}
|
|
397
289
|
}
|
|
398
290
|
catch (e) { }
|
|
@@ -400,11 +292,11 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
400
292
|
}
|
|
401
293
|
}
|
|
402
294
|
async function archiveOutput(packType) {
|
|
403
|
-
const input =
|
|
404
|
-
if ((await
|
|
405
|
-
const archive = new
|
|
295
|
+
const input = path.join(outputFolder, packType.type);
|
|
296
|
+
if ((await fs.readdir(input)).length !== 0) {
|
|
297
|
+
const archive = new AdmZip();
|
|
406
298
|
await archive.addLocalFolderPromise(input, {});
|
|
407
|
-
await archive.writeZipPromise(`${
|
|
299
|
+
await archive.writeZipPromise(`${path.join(outputFolder, 'archives', `${packName}_${packType.type}`)}.zip`, { overwrite: true });
|
|
408
300
|
return true;
|
|
409
301
|
}
|
|
410
302
|
return false;
|
|
@@ -413,15 +305,15 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
413
305
|
if (!cliOptions.production) {
|
|
414
306
|
for await (const _packType of packTypes) {
|
|
415
307
|
const packType = _packType[1];
|
|
416
|
-
const outputPath =
|
|
417
|
-
await
|
|
308
|
+
const outputPath = path.join(outputFolder, packType.type);
|
|
309
|
+
await fs.ensureDir(outputPath);
|
|
418
310
|
if (packType.handleOutput) {
|
|
419
|
-
await packType.handleOutput('output', async (relativePath, encoding = 'utf8') => await
|
|
311
|
+
await packType.handleOutput('output', async (relativePath, encoding = 'utf8') => await fs.readFile(path.join(outputPath, relativePath), encoding), async (relativePath, contents) => {
|
|
420
312
|
if (contents === undefined) {
|
|
421
|
-
await
|
|
313
|
+
await fs.unlink(path.join(outputPath, relativePath));
|
|
422
314
|
}
|
|
423
315
|
else {
|
|
424
|
-
await
|
|
316
|
+
await fs.writeFile(path.join(outputPath, relativePath), contents);
|
|
425
317
|
}
|
|
426
318
|
});
|
|
427
319
|
}
|
|
@@ -431,10 +323,10 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
431
323
|
archivedOutput = await archiveOutput(packType);
|
|
432
324
|
}
|
|
433
325
|
// Handle client
|
|
434
|
-
if (!(server && packType.networkSides === 'server')) {
|
|
326
|
+
if (!(server && packType.networkSides === 'server') && clientPath) {
|
|
435
327
|
let fullClientPath;
|
|
436
328
|
if (worldName) {
|
|
437
|
-
fullClientPath =
|
|
329
|
+
fullClientPath = path.join(clientPath, packType.clientPath);
|
|
438
330
|
try {
|
|
439
331
|
fullClientPath = fullClientPath.replace('$packName$', packName);
|
|
440
332
|
}
|
|
@@ -445,7 +337,7 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
445
337
|
catch { }
|
|
446
338
|
}
|
|
447
339
|
else {
|
|
448
|
-
fullClientPath =
|
|
340
|
+
fullClientPath = path.join(clientPath, packType.rootPath);
|
|
449
341
|
try {
|
|
450
342
|
fullClientPath = fullClientPath.replace('$packName$', packName);
|
|
451
343
|
}
|
|
@@ -453,20 +345,20 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
453
345
|
}
|
|
454
346
|
if (packType.archiveOutput) {
|
|
455
347
|
if (archivedOutput) {
|
|
456
|
-
await
|
|
348
|
+
await fs.copyFile(`${path.join(outputFolder, 'archives', `${packName}_${packType.type}`)}.zip`, `${fullClientPath}.zip`);
|
|
457
349
|
}
|
|
458
350
|
}
|
|
459
351
|
else {
|
|
460
|
-
await
|
|
461
|
-
await
|
|
352
|
+
await fs.remove(fullClientPath);
|
|
353
|
+
await fs.copy(outputPath, fullClientPath);
|
|
462
354
|
}
|
|
463
355
|
if (packType.handleOutput) {
|
|
464
|
-
await packType.handleOutput('client', async (relativePath, encoding = 'utf8') => await
|
|
356
|
+
await packType.handleOutput('client', async (relativePath, encoding = 'utf8') => await fs.readFile(path.join(clientPath, relativePath), encoding), async (relativePath, contents) => {
|
|
465
357
|
if (contents === undefined) {
|
|
466
|
-
|
|
358
|
+
fs.unlink(path.join(clientPath, relativePath));
|
|
467
359
|
}
|
|
468
360
|
else {
|
|
469
|
-
await
|
|
361
|
+
await fs.writeFile(path.join(clientPath, relativePath), contents);
|
|
470
362
|
}
|
|
471
363
|
});
|
|
472
364
|
}
|
|
@@ -479,12 +371,12 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
479
371
|
}
|
|
480
372
|
catch { }
|
|
481
373
|
if (packType.archiveOutput && archivedOutput) {
|
|
482
|
-
await server.writeFile(await
|
|
374
|
+
await server.writeFile(await fs.readFile(`${outputPath}.zip`, 'utf8'), `${serverPath}.zip`);
|
|
483
375
|
}
|
|
484
376
|
else {
|
|
485
377
|
server.remove(serverPath);
|
|
486
|
-
for await (const file of (
|
|
487
|
-
await server.writeFile(
|
|
378
|
+
for await (const file of walk(outputPath)) {
|
|
379
|
+
await server.writeFile(path.join(serverPath, file.path.split(outputPath)[1]), await fs.readFile(file.path));
|
|
488
380
|
}
|
|
489
381
|
}
|
|
490
382
|
if (packType.handleOutput) {
|
|
@@ -495,14 +387,14 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
495
387
|
}
|
|
496
388
|
else {
|
|
497
389
|
for await (const packType of packTypes) {
|
|
498
|
-
const outputPath =
|
|
390
|
+
const outputPath = path.join(outputFolder, packType.type);
|
|
499
391
|
if (packType.handleOutput) {
|
|
500
|
-
await packType.handleOutput('output', async (relativePath, encoding = 'utf8') => await
|
|
392
|
+
await packType.handleOutput('output', async (relativePath, encoding = 'utf8') => await fs.readFile(path.join(outputPath, relativePath), encoding), async (relativePath, contents) => {
|
|
501
393
|
if (contents === undefined) {
|
|
502
|
-
await
|
|
394
|
+
await fs.unlink(path.join(outputPath, relativePath));
|
|
503
395
|
}
|
|
504
396
|
else {
|
|
505
|
-
await
|
|
397
|
+
await fs.writeFile(path.join(outputPath, relativePath), contents);
|
|
506
398
|
}
|
|
507
399
|
});
|
|
508
400
|
}
|
|
@@ -516,13 +408,13 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
516
408
|
const oldFilesNames = new Set(Object.keys(cache));
|
|
517
409
|
Object.keys(newCache).forEach(name => oldFilesNames.delete(name));
|
|
518
410
|
for await (const name of oldFilesNames) {
|
|
519
|
-
await
|
|
411
|
+
await fs.rm(path.join(outputFolder, name));
|
|
520
412
|
}
|
|
521
|
-
await (
|
|
413
|
+
await deleteEmpty(outputFolder);
|
|
522
414
|
// Override old cache
|
|
523
415
|
cache = newCache;
|
|
524
416
|
// Write the cache to disk
|
|
525
|
-
await
|
|
417
|
+
await fs.writeFile(cacheFile, JSON.stringify(cache));
|
|
526
418
|
// Run the afterAll script
|
|
527
419
|
await ((_g = scripts === null || scripts === void 0 ? void 0 : scripts.afterAll) === null || _g === void 0 ? void 0 : _g.call(scripts));
|
|
528
420
|
}
|
|
@@ -532,22 +424,19 @@ async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandsto
|
|
|
532
424
|
* @param options The options to build the project with.
|
|
533
425
|
*
|
|
534
426
|
* @param projectFolder The folder of the project. It needs a sandstone.config.ts, and it or one of its parent needs a package.json.
|
|
535
|
-
*
|
|
536
|
-
* @param changedFiles The files that changed since the last build.
|
|
537
427
|
*/
|
|
538
|
-
async function buildProject(options, folders
|
|
428
|
+
export async function buildProject(options, folders) {
|
|
539
429
|
try {
|
|
540
|
-
await _buildProject(options, folders
|
|
430
|
+
await _buildProject(options, folders);
|
|
541
431
|
}
|
|
542
432
|
catch (err) {
|
|
543
433
|
console.log(err);
|
|
544
434
|
}
|
|
545
435
|
}
|
|
546
|
-
exports.buildProject = buildProject;
|
|
547
436
|
function logError(err, file) {
|
|
548
437
|
if (err) {
|
|
549
438
|
if (file) {
|
|
550
|
-
console.error(' ' +
|
|
439
|
+
console.error(' ' + chalk.bgRed.white('BuildError') + chalk.gray(':'), `While loading "${file}", the following error happened:\n`);
|
|
551
440
|
}
|
|
552
441
|
debugger;
|
|
553
442
|
console.error(pe.render(err));
|
package/lib/commands/build.d.ts
CHANGED
|
@@ -1,29 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
production: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
20
|
-
autoReload: import("@oclif/parser/lib/flags").IOptionFlag<number | undefined>;
|
|
21
|
-
};
|
|
22
|
-
static args: {
|
|
23
|
-
name: string;
|
|
24
|
-
description: string;
|
|
25
|
-
required: boolean;
|
|
26
|
-
default: string;
|
|
27
|
-
}[];
|
|
28
|
-
run(): Promise<void>;
|
|
29
|
-
}
|
|
1
|
+
type BuildOptions = {
|
|
2
|
+
dry?: boolean;
|
|
3
|
+
verbose?: boolean;
|
|
4
|
+
root?: boolean;
|
|
5
|
+
fullTrace?: boolean;
|
|
6
|
+
strictErrors?: boolean;
|
|
7
|
+
production?: boolean;
|
|
8
|
+
path: string;
|
|
9
|
+
configPath: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
namespace?: string;
|
|
12
|
+
world?: string;
|
|
13
|
+
clientPath?: string;
|
|
14
|
+
serverPath?: string;
|
|
15
|
+
ssh?: any;
|
|
16
|
+
};
|
|
17
|
+
export declare function buildCommand(opts: BuildOptions): Promise<void>;
|
|
18
|
+
export {};
|
package/lib/commands/build.js
CHANGED
|
@@ -1,32 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
async run() {
|
|
13
|
-
const { args, flags } = this.parse(Build);
|
|
14
|
-
const folders = (0, utils_1.getProjectFolders)(args.path);
|
|
15
|
-
// Register ts-node
|
|
16
|
-
const tsConfigPath = path_1.default.join(folders.rootFolder, 'tsconfig.json');
|
|
17
|
-
require('ts-node').register({
|
|
18
|
-
transpileOnly: !flags.strictErrors,
|
|
19
|
-
project: tsConfigPath,
|
|
20
|
-
});
|
|
21
|
-
(0, buildProject_1.buildProject)(flags, folders);
|
|
22
|
-
}
|
|
1
|
+
import { register as tsEval } from 'ts-node';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { getProjectFolders } from '../utils.js';
|
|
4
|
+
import { buildProject } from '../build/index.js';
|
|
5
|
+
export async function buildCommand(opts) {
|
|
6
|
+
const folders = getProjectFolders(opts.path);
|
|
7
|
+
tsEval({
|
|
8
|
+
transpileOnly: !opts.strictErrors,
|
|
9
|
+
project: path.join(folders.rootFolder, 'tsconfig.json'),
|
|
10
|
+
});
|
|
11
|
+
buildProject(opts, folders);
|
|
23
12
|
}
|
|
24
|
-
exports.default = Build;
|
|
25
|
-
Build.description = 'Build the packs. ⛏';
|
|
26
|
-
Build.examples = [
|
|
27
|
-
'$ sand build',
|
|
28
|
-
'$ sand build --verbose',
|
|
29
|
-
'$ sand build --verbose --dry',
|
|
30
|
-
];
|
|
31
|
-
Build.flags = watch_1.default.flags;
|
|
32
|
-
Build.args = watch_1.default.args;
|
package/lib/commands/create.d.ts
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
library: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
10
|
-
version: flags.IOptionFlag<string | undefined>;
|
|
11
|
-
'pack-name': flags.IOptionFlag<string | undefined>;
|
|
12
|
-
namespace: flags.IOptionFlag<string | undefined>;
|
|
13
|
-
'save-root': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
14
|
-
world: flags.IOptionFlag<string | undefined>;
|
|
15
|
-
'server-path': flags.IOptionFlag<string | undefined>;
|
|
16
|
-
'client-path': flags.IOptionFlag<string | undefined>;
|
|
17
|
-
};
|
|
18
|
-
static args: {
|
|
19
|
-
name: string;
|
|
20
|
-
description: string;
|
|
21
|
-
required: boolean;
|
|
22
|
-
}[];
|
|
23
|
-
run(): Promise<void>;
|
|
24
|
-
}
|
|
1
|
+
type CreateOptions = {
|
|
2
|
+
root: boolean;
|
|
3
|
+
world?: string;
|
|
4
|
+
clientPath?: string;
|
|
5
|
+
serverPath?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function createCommand(_project: string, opts: CreateOptions): Promise<void>;
|
|
8
|
+
export {};
|