@tapestry-mud/cli 0.3.8 → 0.3.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapestry-mud/cli",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "CLI for the Tapestry MUD engine",
5
5
  "bin": {
6
6
  "tapestry": "./bin/tapestry.js"
@@ -4,6 +4,10 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const { fetchPreset, fetchPresetList, DEFAULT_REGISTRY } = require('../lib/registry-client');
6
6
 
7
+ function slugify(str) {
8
+ return str.trim().toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9_.-]/g, '');
9
+ }
10
+
7
11
  function buildManifest(name, deps, engineVersion, engineChannel) {
8
12
  const depLines = Object.entries(deps)
9
13
  .map(([pkg, range]) => ` '${pkg}': '${range}'`)
@@ -154,7 +158,6 @@ async function init(cwd, { registryUrl = DEFAULT_REGISTRY, yes = false, prompter
154
158
  gameName: dirName,
155
159
  adminHandle: 'admin',
156
160
  adminPassword: 'changeme',
157
- serverName: dirName,
158
161
  telemetry: false,
159
162
  };
160
163
  console.warn('Default admin credentials -- change in server.yaml before production use.');
@@ -166,7 +169,7 @@ async function init(cwd, { registryUrl = DEFAULT_REGISTRY, yes = false, prompter
166
169
  name: 'gameName',
167
170
  message: 'Game name:',
168
171
  default: dirName,
169
- validate: (v) => (v.trim().length > 0 && /^[a-zA-Z0-9_.-]+$/.test(v.trim())) || 'Must be non-empty and filesystem-safe',
172
+ validate: (v) => v.trim().length > 0 || 'Required',
170
173
  },
171
174
  {
172
175
  type: 'input',
@@ -188,13 +191,6 @@ async function init(cwd, { registryUrl = DEFAULT_REGISTRY, yes = false, prompter
188
191
  mask: '*',
189
192
  validate: (v, a) => v === a.adminPassword || 'Passwords do not match',
190
193
  },
191
- {
192
- type: 'input',
193
- name: 'serverName',
194
- message: 'Server name:',
195
- default: (a) => a.gameName,
196
- validate: (v) => v.trim().length > 0 || 'Required',
197
- },
198
194
  {
199
195
  type: 'confirm',
200
196
  name: 'telemetry',
@@ -204,13 +200,13 @@ async function init(cwd, { registryUrl = DEFAULT_REGISTRY, yes = false, prompter
204
200
  ]);
205
201
  }
206
202
 
207
- const name = answers.gameName;
203
+ const name = slugify(answers.gameName);
208
204
 
209
205
  fs.writeFileSync(manifestPath, buildManifest(name, deps, preset.version, preset.engine_channel));
210
206
  fs.writeFileSync(
211
207
  path.join(cwd, 'server.yaml'),
212
208
  buildServerYaml({
213
- serverName: answers.serverName,
209
+ serverName: answers.gameName,
214
210
  adminHandle: answers.adminHandle,
215
211
  adminPassword: answers.adminPassword,
216
212
  telemetry: answers.telemetry,
@@ -247,4 +243,4 @@ async function init(cwd, { registryUrl = DEFAULT_REGISTRY, yes = false, prompter
247
243
  }
248
244
  }
249
245
 
250
- module.exports = { init, buildManifest, buildServerYaml };
246
+ module.exports = { init, buildManifest, buildServerYaml, slugify };
@@ -65,11 +65,11 @@ function dockerEnsureImage(image, version) {
65
65
  }
66
66
  }
67
67
 
68
- function dockerStart(projectName, image, version, packsDir, serverYamlPath, dataDir) {
68
+ function dockerStart(projectName, image, version, packsDir, serverYamlPath, dataDir, network) {
69
69
  const containerName = `tapestry-${projectName}`;
70
70
  dockerEnsureImage(image, version);
71
71
  spawnSync('docker', ['rm', '-f', containerName], { stdio: 'ignore' });
72
- const result = spawnSync('docker', [
72
+ const args = [
73
73
  'run', '--detach',
74
74
  '--name', containerName,
75
75
  '-p', '4000:4000',
@@ -77,8 +77,12 @@ function dockerStart(projectName, image, version, packsDir, serverYamlPath, data
77
77
  '-v', `${packsDir}:/app/packs`,
78
78
  '-v', `${serverYamlPath}:/app/server.yaml`,
79
79
  '-v', `${dataDir}:/app/data`,
80
- `${image}:${version}`,
81
- ], { stdio: 'inherit' });
80
+ ];
81
+ if (network) {
82
+ args.push('--network', network);
83
+ }
84
+ args.push(`${image}:${version}`);
85
+ const result = spawnSync('docker', args, { stdio: 'inherit' });
82
86
  if (result.status !== 0) {
83
87
  throw new Error(
84
88
  `docker run failed. Ensure the image exists and no container named '${containerName}' is already running.`
@@ -261,6 +265,7 @@ function readEngineConfig(cwd) {
261
265
  version: engine.version,
262
266
  mode: engine.mode,
263
267
  image: engine.image || DEFAULT_IMAGE,
268
+ network: engine.network || null,
264
269
  installDir: path.join(cwd, '.tapestry-engine'),
265
270
  projectName: (manifest.name || 'tapestry').toLowerCase().replace(/[^a-z0-9-]+/g, '-'),
266
271
  };
@@ -317,7 +322,7 @@ async function startEngine(cwd) {
317
322
  fs.mkdirSync(dataDir, { recursive: true });
318
323
  if (config.mode === 'docker') {
319
324
  const tag = await resolveDockerTag(config);
320
- dockerStart(config.projectName, config.image, tag, packsDir, serverYamlPath, dataDir);
325
+ dockerStart(config.projectName, config.image, tag, packsDir, serverYamlPath, dataDir, config.network);
321
326
  } else if (config.mode === 'binary') {
322
327
  binaryStart(config.version, config.installDir, packsDir, serverYamlPath, cwd);
323
328
  } else {