sandstone-cli 0.6.5 → 1.0.0
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/index.js +446 -0
- 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 -165
- 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 +48 -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/buildProject.js +0 -558
- 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
package/lib/commands/create.js
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
11
|
-
const path_1 = __importDefault(require("path"));
|
|
12
|
-
const util_1 = __importDefault(require("util"));
|
|
13
|
-
const utils_1 = require("../utils");
|
|
14
|
-
const nanoid_1 = require("nanoid");
|
|
1
|
+
import { SemVer } from 'semver';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import util from 'util';
|
|
6
|
+
import * as child from 'child_process';
|
|
7
|
+
import { nanoid } from 'nanoid';
|
|
8
|
+
import { capitalize, getWorldsList, hasPnpm, hasYarn } from '../utils.js';
|
|
15
9
|
function toJson(obj, pretty = false) {
|
|
16
|
-
return
|
|
10
|
+
return util.inspect(obj, {
|
|
17
11
|
depth: Number(Infinity),
|
|
18
12
|
colors: false,
|
|
19
13
|
breakLength: Number(Infinity),
|
|
@@ -21,165 +15,156 @@ function toJson(obj, pretty = false) {
|
|
|
21
15
|
maxArrayLength: Number(Infinity),
|
|
22
16
|
});
|
|
23
17
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
export async function createCommand(_project, opts) {
|
|
19
|
+
const projectPath = path.resolve(_project);
|
|
20
|
+
const projectName = path.basename(projectPath);
|
|
21
|
+
const inquirer = (await import("inquirer")).default;
|
|
22
|
+
const projectType = Boolean((await inquirer.prompt({
|
|
23
|
+
name: 'projectType',
|
|
24
|
+
message: 'Whether your project will be a library for use in other Sandstone projects >',
|
|
25
|
+
type: 'confirm',
|
|
26
|
+
default: false,
|
|
27
|
+
})).projectType) === true ? 'library' : 'pack';
|
|
28
|
+
const sv = (v) => new SemVer(v);
|
|
29
|
+
const versions = [[sv('0.13.6'), sv('0.5.4')], [sv('0.14.0-alpha.13'), sv('0.5.4')], [sv('1.0.0-alpha.1'), sv('1.0.0')]];
|
|
30
|
+
const stableIndex = 0;
|
|
31
|
+
const { version } = await inquirer.prompt({
|
|
32
|
+
name: 'version',
|
|
33
|
+
type: 'list',
|
|
34
|
+
message: 'Which version of Sandstone do you want to use? These are the only supported versions for new projects.',
|
|
35
|
+
choices: versions.map((v) => {
|
|
36
|
+
const { prerelease, major, minor } = v[0];
|
|
37
|
+
const release = `${major}.${minor}`;
|
|
38
|
+
return {
|
|
39
|
+
name: prerelease.length === 0 ?
|
|
40
|
+
`Release Version ${release}` :
|
|
41
|
+
`${capitalize(prerelease[0])} Version ${prerelease[1]} for release ${release}`,
|
|
42
|
+
value: v,
|
|
43
|
+
short: v[0].toString(),
|
|
44
|
+
};
|
|
45
|
+
}),
|
|
46
|
+
default: stableIndex,
|
|
47
|
+
});
|
|
48
|
+
let packName = projectName;
|
|
49
|
+
let namespace = projectName.replace(RegExp(/ /g), '_');
|
|
50
|
+
if (projectType === 'pack') {
|
|
51
|
+
packName = (await inquirer.prompt({
|
|
52
|
+
name: 'projectType',
|
|
53
|
+
message: 'Name of your output pack(s) (can be changed later) >',
|
|
54
|
+
default: projectName,
|
|
31
55
|
type: 'input',
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
type: 'input',
|
|
53
|
-
default: projectName,
|
|
54
|
-
});
|
|
55
|
-
namespace = await (0, utils_1.getFlagOrPrompt)(flags, 'namespace', {
|
|
56
|
-
message: 'Default namespace (can be changed later) >',
|
|
57
|
-
default: 'default',
|
|
58
|
-
});
|
|
56
|
+
})).projectType;
|
|
57
|
+
namespace = (await inquirer.prompt({
|
|
58
|
+
name: 'namespace',
|
|
59
|
+
message: 'Default namespace (can be changed later) >',
|
|
60
|
+
default: namespace,
|
|
61
|
+
type: 'input',
|
|
62
|
+
})).namespace;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
packName += '-testing';
|
|
66
|
+
namespace += '_test';
|
|
67
|
+
}
|
|
68
|
+
// Find the save directory
|
|
69
|
+
const saveOptions = {};
|
|
70
|
+
if (version[0].major === 1) {
|
|
71
|
+
if (opts.root) {
|
|
72
|
+
saveOptions.root = true;
|
|
73
|
+
}
|
|
74
|
+
else if (opts.world) {
|
|
75
|
+
saveOptions.world = opts.world;
|
|
59
76
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
77
|
+
else if (opts.serverPath) {
|
|
78
|
+
saveOptions.serverPath = opts.serverPath;
|
|
79
|
+
}
|
|
80
|
+
else { // TODO: Add support for ssh
|
|
81
|
+
// User didn't specify a way to save the file. Ask them.
|
|
82
|
+
const { saveChoice } = await inquirer.prompt({
|
|
83
|
+
name: 'saveChoice',
|
|
84
|
+
type: 'list',
|
|
85
|
+
message: 'Where do you want your pack(s) to be saved (can be changed later)?',
|
|
86
|
+
choices: [{
|
|
87
|
+
name: 'In the root client (.minecraft) folder',
|
|
88
|
+
value: 'root',
|
|
89
|
+
short: 'Client folder',
|
|
90
|
+
}, {
|
|
91
|
+
name: 'In a world',
|
|
92
|
+
value: 'world',
|
|
93
|
+
short: 'World',
|
|
94
|
+
}, {
|
|
95
|
+
name: 'In a server',
|
|
96
|
+
value: 'server-path',
|
|
97
|
+
short: 'Server path',
|
|
98
|
+
}],
|
|
99
|
+
});
|
|
100
|
+
if (saveChoice === 'root') {
|
|
64
101
|
saveOptions.root = true;
|
|
65
102
|
}
|
|
66
|
-
else if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
saveOptions.serverPath = flags['server-path'];
|
|
71
|
-
}
|
|
72
|
-
else { // TODO: Add support for ssh
|
|
73
|
-
// User didn't specify a way to save the file. Ask them.
|
|
74
|
-
const { saveChoice } = await inquirer_1.default.prompt({
|
|
75
|
-
name: 'saveChoice',
|
|
103
|
+
else if (saveChoice === 'world') {
|
|
104
|
+
const { world } = await inquirer.prompt({
|
|
105
|
+
name: 'World',
|
|
106
|
+
message: 'What world do you want to save the packs in? >',
|
|
76
107
|
type: 'list',
|
|
77
|
-
|
|
78
|
-
choices: [{
|
|
79
|
-
name: 'In the root client (.minecraft) folder',
|
|
80
|
-
value: 'root',
|
|
81
|
-
short: 'Client folder',
|
|
82
|
-
}, {
|
|
83
|
-
name: 'In a world',
|
|
84
|
-
value: 'world',
|
|
85
|
-
short: 'World',
|
|
86
|
-
}, {
|
|
87
|
-
name: 'In a server',
|
|
88
|
-
value: 'server-path',
|
|
89
|
-
short: 'Server path',
|
|
90
|
-
}],
|
|
108
|
+
choices: getWorldsList,
|
|
91
109
|
});
|
|
92
|
-
|
|
93
|
-
saveOptions.root = true;
|
|
94
|
-
}
|
|
95
|
-
else if (saveChoice === 'world') {
|
|
96
|
-
const { world } = await inquirer_1.default.prompt({
|
|
97
|
-
name: 'World',
|
|
98
|
-
message: 'What world do you want to save the packs in? >',
|
|
99
|
-
type: 'list',
|
|
100
|
-
choices: utils_1.getWorldsList,
|
|
101
|
-
});
|
|
102
|
-
saveOptions.world = world;
|
|
103
|
-
}
|
|
104
|
-
else { // TODO: Add native folder selector
|
|
105
|
-
const { serverPath } = await inquirer_1.default.prompt({
|
|
106
|
-
name: 'Server path',
|
|
107
|
-
message: 'Where is the server to save the packs in? Relative paths are accepted. >',
|
|
108
|
-
type: 'input',
|
|
109
|
-
});
|
|
110
|
-
saveOptions.serverPath = serverPath;
|
|
111
|
-
}
|
|
110
|
+
saveOptions.world = world;
|
|
112
111
|
}
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
else { // TODO: Add native folder selector
|
|
113
|
+
const { serverPath } = await inquirer.prompt({
|
|
114
|
+
name: 'Server path',
|
|
115
|
+
message: 'Where is the server to save the packs in? Relative paths are accepted. >',
|
|
116
|
+
type: 'input',
|
|
117
|
+
});
|
|
118
|
+
saveOptions.serverPath = serverPath;
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
useYarn = (await inquirer_1.default.prompt({
|
|
120
|
-
name: 'useYarn',
|
|
121
|
-
message: 'What package manager do you want to use? >',
|
|
122
|
-
type: 'list',
|
|
123
|
-
choices: ['npm', 'yarn'],
|
|
124
|
-
})).useYarn === 'yarn';
|
|
125
|
-
}
|
|
126
|
-
fs_extra_1.default.mkdirSync(projectPath);
|
|
127
|
-
// Create project & install dependencies
|
|
128
|
-
this.log((0, chalk_1.default) `Installing {rgb(229,193,0) sandstone@${sandstoneVersion[0]}}, {rgb(229,193,0) sandstone-cli@${sandstoneVersion[1]}} and {cyan typescript} using {cyan ${useYarn ? 'yarn' : 'npm'}}.`);
|
|
129
|
-
const exec = (cmd) => (0, child_process_1.execSync)(cmd, { cwd: projectPath });
|
|
130
|
-
exec('git clone https://github.com/sandstone-mc/sandstone-template.git .');
|
|
131
|
-
exec(`git checkout ${projectType}-${sandstoneVersion[0]}`);
|
|
132
|
-
exec('npx rimraf -rf .git');
|
|
133
|
-
exec(`${useYarn ? 'yarn' : 'npm'} install`);
|
|
134
|
-
// TODO: Make profiles for either packs or libraries
|
|
135
|
-
const configPath = path_1.default.join(projectPath, `${projectType === 'library' ? 'test/' : ''}sandstone.config.ts`);
|
|
136
|
-
// Merge with the config values
|
|
137
|
-
let templateConfig = await fs_extra_1.default.readFile(configPath, 'utf8');
|
|
138
|
-
templateConfig = templateConfig.replace('packUid: \'kZZpDK67\'', `packUid: ${toJson((0, nanoid_1.nanoid)(8))}`);
|
|
139
|
-
let _name = packName;
|
|
140
|
-
let _namespace = namespace;
|
|
141
|
-
if (projectType === 'library') {
|
|
142
|
-
_name += '-testing';
|
|
143
|
-
_namespace += '_test';
|
|
144
|
-
}
|
|
145
|
-
templateConfig = templateConfig.replace('name: \'template\'', `name: ${toJson(_name)}`);
|
|
146
|
-
templateConfig = templateConfig.replace('namespace: \'default\'', `namespace: ${toJson(_namespace)}`);
|
|
147
|
-
// TODO: packFormat
|
|
148
|
-
const opts = toJson(Object.fromEntries(Object.entries(saveOptions).filter(([_, value]) => value !== undefined)));
|
|
149
|
-
if (opts !== '{}') {
|
|
150
|
-
templateConfig = templateConfig.replace('saveOptions: {}', `saveOptions: ${opts}`);
|
|
121
|
+
if (opts.clientPath) {
|
|
122
|
+
saveOptions.clientPath = opts.clientPath;
|
|
151
123
|
}
|
|
152
|
-
// Rewrite config
|
|
153
|
-
fs_extra_1.default.writeFileSync(configPath, templateConfig);
|
|
154
|
-
const prefix = useYarn ? 'yarn' : 'npm run';
|
|
155
|
-
this.log((0, chalk_1.default) `{green Success!} Created "${projectName}" at "${projectPath}"`);
|
|
156
|
-
this.log('Inside that directory, you can run several commands:\n');
|
|
157
|
-
this.log((0, chalk_1.default) ` {cyan ${prefix} build}:\n Builds the packs. {cyan ⛏}\n`);
|
|
158
|
-
this.log((0, chalk_1.default) ` {cyan ${prefix} watch}:\n Builds the packs, and rebuilds on each file change. {cyan ⛏}\n`);
|
|
159
|
-
this.log('We suggest that you begin by typing:\n');
|
|
160
|
-
this.log((0, chalk_1.default) ` {cyan cd} ${projectName}\n {cyan ${prefix} watch}`);
|
|
161
124
|
}
|
|
125
|
+
let packageManager = 'npm';
|
|
126
|
+
const yarn = hasYarn();
|
|
127
|
+
const pnpm = hasPnpm();
|
|
128
|
+
if (yarn || pnpm) {
|
|
129
|
+
const choices = ['npm'];
|
|
130
|
+
if (yarn)
|
|
131
|
+
choices.unshift('yarn');
|
|
132
|
+
if (pnpm)
|
|
133
|
+
choices.unshift('pnpm');
|
|
134
|
+
packageManager = (await inquirer.prompt({
|
|
135
|
+
name: 'packageManager',
|
|
136
|
+
message: 'What package manager do you want to use? >',
|
|
137
|
+
type: 'list',
|
|
138
|
+
choices: choices,
|
|
139
|
+
})).packageManager;
|
|
140
|
+
}
|
|
141
|
+
fs.mkdirSync(projectPath);
|
|
142
|
+
// Create project & install dependencies
|
|
143
|
+
console.log(chalk `Installing {rgb(229,193,0) sandstone@${version[0]}}, {rgb(229,193,0) sandstone-cli@${version[1]}} and {cyan typescript} using {cyan ${packageManager}}.`);
|
|
144
|
+
const exec = (cmd) => child.execSync(cmd, { cwd: projectPath });
|
|
145
|
+
exec('git clone https://github.com/sandstone-mc/sandstone-template.git .');
|
|
146
|
+
exec(`git checkout ${projectType}-${version[0]}`);
|
|
147
|
+
exec('npx rimraf -rf .git');
|
|
148
|
+
exec(`${packageManager} install`);
|
|
149
|
+
// TODO: Make profiles for either packs or libraries
|
|
150
|
+
const configPath = path.join(projectPath, `${projectType === 'library' ? 'test/' : ''}sandstone.config.ts`);
|
|
151
|
+
// Merge with the config values
|
|
152
|
+
let templateConfig = await fs.readFile(configPath, 'utf8');
|
|
153
|
+
templateConfig = templateConfig.replace('packUid: \'kZZpDK67\'', `packUid: ${toJson(nanoid(8))}`);
|
|
154
|
+
templateConfig = templateConfig.replace('name: \'template\'', `name: ${toJson(packName)}`);
|
|
155
|
+
templateConfig = templateConfig.replace('namespace: \'default\'', `namespace: ${toJson(namespace)}`);
|
|
156
|
+
// TODO: packFormat
|
|
157
|
+
const optsJson = toJson(Object.fromEntries(Object.entries(saveOptions).filter(([_, value]) => value !== undefined)));
|
|
158
|
+
if (optsJson !== '{}') {
|
|
159
|
+
templateConfig = templateConfig.replace('saveOptions: {}', `saveOptions: ${optsJson}`);
|
|
160
|
+
}
|
|
161
|
+
// Rewrite config
|
|
162
|
+
fs.writeFileSync(configPath, templateConfig);
|
|
163
|
+
const prefix = packageManager === 'npm' ? 'npm run' : packageManager;
|
|
164
|
+
console.log(chalk `{green Success!} Created "${projectName}" at "${projectPath}"`);
|
|
165
|
+
console.log('Inside that directory, you can run several commands:\n');
|
|
166
|
+
console.log(chalk ` {cyan ${prefix} build}:\n Builds the packs. {cyan ⛏}\n`);
|
|
167
|
+
console.log(chalk ` {cyan ${prefix} watch}:\n Builds the packs, and rebuilds on each file change. {cyan ⛏}\n`);
|
|
168
|
+
console.log('We suggest that you begin by typing:\n');
|
|
169
|
+
console.log(chalk ` {cyan cd} ${projectName}\n {cyan ${prefix} watch}`);
|
|
162
170
|
}
|
|
163
|
-
exports.default = Create;
|
|
164
|
-
Create.description = 'Create a new Sandstone project.';
|
|
165
|
-
Create.examples = [
|
|
166
|
-
'$ sand create my-pack',
|
|
167
|
-
];
|
|
168
|
-
Create.flags = {
|
|
169
|
-
help: command_1.flags.help({ char: 'h' }),
|
|
170
|
-
yarn: command_1.flags.boolean({ description: 'Use yarn instead of npm.', env: 'USE_YARN', exclusive: ['npm'] }),
|
|
171
|
-
npm: command_1.flags.boolean({ description: 'Use npm.', env: 'USE_NPM', exclusive: ['yarn'] }),
|
|
172
|
-
library: command_1.flags.boolean({ char: 't', env: 'LIBRARY', description: 'Whether the project will be a library for use in other Sandstone projects.' }),
|
|
173
|
-
version: command_1.flags.string({ char: 'v', env: 'SANDSTONE_VERSION', description: 'What version of Sandstone you\'d like to create a project for.' }),
|
|
174
|
-
'pack-name': command_1.flags.string({ char: 'd', env: 'PACK_NAME', description: 'The name of the pack(s).' }),
|
|
175
|
-
namespace: command_1.flags.string({ char: 'n', env: 'NAMESPACE', description: 'The default namespace that will be used.' }),
|
|
176
|
-
'save-root': command_1.flags.boolean({ char: 'r', env: 'SAVE_ROOT', description: 'Save the datapack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Not compatible with --world.', exclusive: ['world'] }),
|
|
177
|
-
world: command_1.flags.string({ char: 'w', env: 'WORLD', description: 'The world to save the packs in. Not compatible with --save-root or --server', exclusive: ['save-root', 'server'] }),
|
|
178
|
-
'server-path': command_1.flags.string({ char: 's', env: 'SERVER_PATH', description: 'The server path to write the server-side packs at. Not compatible with --world.', exclusive: ['world'] }),
|
|
179
|
-
'client-path': command_1.flags.string({ char: 'c', env: 'CLIENT_PATH', description: 'The client path to write packs at.' }),
|
|
180
|
-
};
|
|
181
|
-
Create.args = [{
|
|
182
|
-
name: 'project-name',
|
|
183
|
-
description: 'Name of the project folder. This is not the name of the output pack(s).',
|
|
184
|
-
required: true,
|
|
185
|
-
}];
|
package/lib/commands/watch.d.ts
CHANGED
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
fullTrace: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
18
|
-
strictErrors: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
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 WatchOptions = {
|
|
2
|
+
dry?: boolean;
|
|
3
|
+
verbose?: boolean;
|
|
4
|
+
root?: boolean;
|
|
5
|
+
fullTrace?: boolean;
|
|
6
|
+
strictErrors?: boolean;
|
|
7
|
+
path: string;
|
|
8
|
+
configPath: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
namespace?: string;
|
|
11
|
+
world?: string;
|
|
12
|
+
clientPath?: string;
|
|
13
|
+
serverPath?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function watchCommand(opts: WatchOptions): Promise<void>;
|
|
16
|
+
export {};
|
package/lib/commands/watch.js
CHANGED
|
@@ -1,110 +1,65 @@
|
|
|
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
|
-
}
|
|
1
|
+
import { register as tsEval } from 'ts-node';
|
|
2
|
+
import chokidar from 'chokidar';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { buildProject } from '../build/index.js';
|
|
5
|
+
import { getProjectFolders } from '../utils.js';
|
|
6
|
+
export async function watchCommand(opts) {
|
|
7
|
+
let alreadyBuilding = false;
|
|
8
|
+
let needRebuild = false;
|
|
9
|
+
// let client: Client | null = null
|
|
10
|
+
// TODO: add support for clients & resources that require restarts & world resets, sandstone-server should override the involved environment variables if mods are present that fix it
|
|
11
|
+
/*if (flags.autoReload !== undefined) {
|
|
12
|
+
try {
|
|
13
|
+
client = (await require('minecraft-protocol')).createClient({
|
|
14
|
+
username: 'SandstoneBot',
|
|
15
|
+
host: 'localhost',
|
|
16
|
+
port: flags.autoReload,
|
|
17
|
+
})
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.log(chalk.rgb(255, 204, 0)`Failed to connect to localhost:${flags.autoReload}. The datapack won't be auto reloaded.`)
|
|
20
|
+
}
|
|
21
|
+
}*/
|
|
22
|
+
const folders = getProjectFolders(opts.path);
|
|
23
|
+
async function onFilesChange() {
|
|
24
|
+
if (alreadyBuilding) {
|
|
25
|
+
// If the pack is already being built & another change was made,
|
|
26
|
+
// notify that a rebuild is needed & stop there
|
|
27
|
+
needRebuild = true;
|
|
28
|
+
return;
|
|
30
29
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
alreadyBuilding = true;
|
|
40
|
-
await (0, buildProject_1.buildProject)(flags, folders, paths);
|
|
41
|
-
client === null || client === void 0 ? void 0 : client.write('chat', { message: '/reload' });
|
|
42
|
-
alreadyBuilding = false;
|
|
43
|
-
if (needRebuild) {
|
|
44
|
-
needRebuild = false;
|
|
45
|
-
await onFilesChange(paths);
|
|
46
|
-
}
|
|
30
|
+
alreadyBuilding = true;
|
|
31
|
+
await buildProject(opts, folders);
|
|
32
|
+
//client?.write('chat', { message: '/reload' })
|
|
33
|
+
alreadyBuilding = false;
|
|
34
|
+
if (needRebuild) {
|
|
35
|
+
needRebuild = false;
|
|
36
|
+
await onFilesChange();
|
|
47
37
|
}
|
|
48
|
-
// Register ts-node
|
|
49
|
-
const tsConfigPath = path_1.default.join(folders.rootFolder, 'tsconfig.json');
|
|
50
|
-
require('ts-node').register({
|
|
51
|
-
transpileOnly: !flags.strictErrors,
|
|
52
|
-
project: tsConfigPath,
|
|
53
|
-
});
|
|
54
|
-
let timeout = null;
|
|
55
|
-
let files = [];
|
|
56
|
-
chokidar_1.default.watch([
|
|
57
|
-
path_1.default.join(folders.absProjectFolder, '/**/*'),
|
|
58
|
-
path_1.default.join(folders.sandstoneConfigFolder, 'sandstone.config.ts'),
|
|
59
|
-
path_1.default.join(folders.rootFolder, 'package.json'),
|
|
60
|
-
path_1.default.join(folders.rootFolder, 'tsconfig.json'),
|
|
61
|
-
]).on('all', (event, path) => {
|
|
62
|
-
if (event === 'addDir') {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
files.push(path);
|
|
66
|
-
if (timeout)
|
|
67
|
-
clearTimeout(timeout);
|
|
68
|
-
timeout = setTimeout(() => {
|
|
69
|
-
onFilesChange(files.length === 0 ? undefined : files);
|
|
70
|
-
files = [];
|
|
71
|
-
}, 200);
|
|
72
|
-
});
|
|
73
38
|
}
|
|
39
|
+
// Register ts-node
|
|
40
|
+
const tsConfigPath = path.join(folders.rootFolder, 'tsconfig.json');
|
|
41
|
+
tsEval({
|
|
42
|
+
transpileOnly: !opts.strictErrors,
|
|
43
|
+
project: tsConfigPath,
|
|
44
|
+
});
|
|
45
|
+
let timeout = null;
|
|
46
|
+
let files = [];
|
|
47
|
+
chokidar.watch([
|
|
48
|
+
path.join(folders.absProjectFolder, '/**/*'),
|
|
49
|
+
path.join(folders.sandstoneConfigFolder, 'sandstone.config.ts'),
|
|
50
|
+
path.join(folders.rootFolder, 'package.json'),
|
|
51
|
+
path.join(folders.rootFolder, 'tsconfig.json'),
|
|
52
|
+
/* @ts-ignore */
|
|
53
|
+
]).on('all', (event, path) => {
|
|
54
|
+
if (event === 'addDir') {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
files.push(path);
|
|
58
|
+
if (timeout)
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
timeout = setTimeout(() => {
|
|
61
|
+
onFilesChange();
|
|
62
|
+
files = [];
|
|
63
|
+
}, 200);
|
|
64
|
+
});
|
|
74
65
|
}
|
|
75
|
-
exports.default = Watch;
|
|
76
|
-
Watch.description = 'Build the packs, and rebuild them on file change. ⛏';
|
|
77
|
-
Watch.examples = [
|
|
78
|
-
'$ sand watch',
|
|
79
|
-
'$ sand watch --verbose',
|
|
80
|
-
'$ sand watch --verbose --dry',
|
|
81
|
-
];
|
|
82
|
-
Watch.flags = {
|
|
83
|
-
help: command_1.flags.help({ char: 'h' }),
|
|
84
|
-
dry: command_1.flags.boolean({ char: 'd', description: 'Do not save the pack. Mostly useful with `verbose`.' }),
|
|
85
|
-
verbose: command_1.flags.boolean({ char: 'v', description: 'Log all resulting resources: functions, advancements...' }),
|
|
86
|
-
namespace: command_1.flags.string({ description: 'The default namespace. Override the value specified in the configuration file.' }),
|
|
87
|
-
world: command_1.flags.string({ description: 'The world to save the datapack in. Override the value specified in the configuration file.' }),
|
|
88
|
-
root: command_1.flags.boolean({ description: 'Save the datapack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Override the value specified in the configuration file.' }),
|
|
89
|
-
clientPath: command_1.flags.string({ name: 'client-path', description: 'Path of the client folder. Override the value specified in the configuration file.' }),
|
|
90
|
-
serverPath: command_1.flags.string({ name: 'server-path', description: 'Path of the server folder. Override the value specified in the configuration file.' }),
|
|
91
|
-
// TODO: ssh
|
|
92
|
-
name: command_1.flags.string({ description: 'Name of the datapack. Override the value specified in the configuration file.' }),
|
|
93
|
-
description: command_1.flags.string({ description: 'Description of the datapack. Override the value specified in the configuration file.' }),
|
|
94
|
-
formatVersion: command_1.flags.integer({ name: 'format', description: 'Pack format version. Override the value specified in the configuration file.' }),
|
|
95
|
-
fullTrace: command_1.flags.boolean({ name: 'full-trace', description: 'Show the full stack trace on errors.' }),
|
|
96
|
-
strictErrors: command_1.flags.boolean({ description: 'Stop datapack compilation on type errors.', default: false }),
|
|
97
|
-
production: command_1.flags.boolean({ char: 'p', description: 'Runs Sandstone in production mode. This sets process.env.SANDSTONE_ENV to "production".', default: false }),
|
|
98
|
-
autoReload: command_1.flags.integer({ description: 'Automatically reload your datapack in-game. Requires to open the world to LAN with cheats enabled, and to specify the port.', helpValue: 'port' }),
|
|
99
|
-
};
|
|
100
|
-
Watch.args = [{
|
|
101
|
-
name: 'path',
|
|
102
|
-
description: 'Path of the folder containing source files.',
|
|
103
|
-
required: true,
|
|
104
|
-
default: './src',
|
|
105
|
-
}, {
|
|
106
|
-
name: 'config-path',
|
|
107
|
-
description: 'Path of the sandstone.config.ts folder.',
|
|
108
|
-
required: true,
|
|
109
|
-
default: '.',
|
|
110
|
-
}];
|
package/lib/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export {};
|