create-vimp-game 0.2.0 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vimp-game",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Scaffolder for VIMP game plugins",
5
5
  "keywords": [
6
6
  "vimp",
package/src/cli.js CHANGED
@@ -26,6 +26,8 @@ export const USAGE = `Usage: create-vimp-game <directory> [options]
26
26
  --title <title> human-readable title
27
27
  --package <name> npm package name (default: @vimp-games/<id>)
28
28
  --author <name>
29
+ --repository <url> project repository (URL or user/repo) — the engine links
30
+ to it from the game's entry form
29
31
  --yes, -y accept all defaults, no prompts
30
32
  --force allow a non-empty target directory
31
33
  --no-git skip \`git init\`
@@ -39,6 +41,7 @@ const VALUE_OPTIONS = new Map([
39
41
  ['--title', 'title'],
40
42
  ['--package', 'packageName'],
41
43
  ['--author', 'author'],
44
+ ['--repository', 'repository'],
42
45
  ['--engine-path', 'enginePath'],
43
46
  ['--core-path', 'corePath'],
44
47
  ]);
@@ -114,6 +117,9 @@ export function buildDefaults(args) {
114
117
  title: args.title ?? defaultTitle(id),
115
118
  packageName: args.packageName ?? defaultPackageName(id),
116
119
  author: args.author ?? '',
120
+ // репозиторий не выводится из author: тот — имя человека, а не логин на
121
+ // хостинге, и угаданный URL уехал бы битой ссылкой в футер к игрокам
122
+ repository: args.repository ?? '',
117
123
  };
118
124
  }
119
125
 
@@ -200,6 +206,7 @@ export async function main(argv) {
200
206
  force: args.force === true,
201
207
  enginePath: args.enginePath,
202
208
  corePath: args.corePath,
209
+ repository: answers.repository,
203
210
  });
204
211
 
205
212
  if (args.git) {
package/src/generator.js CHANGED
@@ -144,6 +144,29 @@ async function applyEnginePath(targetDir, enginePath) {
144
144
  await writeFile(file, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
145
145
  }
146
146
 
147
+ // Адрес проекта в package.json: движок берёт из него ссылку в футере формы
148
+ // входа (docs/en/client.md), а правило контракта A7 предупреждает, когда поля
149
+ // нет. Пишется только по явно заданному значению — угаданный URL уехал бы
150
+ // битой ссылкой к игрокам.
151
+ //
152
+ // Раскрывается лишь шорткат `user/repo`: у пакета нулевые рантайм-зависимости,
153
+ // поэтому движковый resolveProjectUrl сюда не импортируется — все остальные
154
+ // формы (`git+ssh://`, хвост `.git`) он разбирает уже при чтении.
155
+ async function applyRepository(targetDir, repository) {
156
+ const value = repository.trim();
157
+ const url = /^[\w.-]+\/[\w.-]+$/.test(value)
158
+ ? `https://github.com/${value}`
159
+ : value;
160
+
161
+ const file = path.join(targetDir, 'package.json');
162
+ const manifest = JSON.parse(await readFile(file, 'utf8'));
163
+
164
+ manifest.repository = { type: 'git', url: `git+${url}.git` };
165
+ manifest.homepage = `${url}#readme`;
166
+
167
+ await writeFile(file, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
168
+ }
169
+
147
170
  async function applyCorePath(targetDir, corePath) {
148
171
  const file = path.join(targetDir, 'Cargo.toml');
149
172
  const patch =
@@ -171,6 +194,7 @@ export async function generate({
171
194
  force = false,
172
195
  enginePath,
173
196
  corePath,
197
+ repository = '',
174
198
  }) {
175
199
  await ensureTargetDir(targetDir, { force });
176
200
 
@@ -185,6 +209,13 @@ export async function generate({
185
209
  await applyEnginePath(targetDir, enginePath);
186
210
  }
187
211
 
212
+ if (
213
+ repository.trim() !== '' &&
214
+ (await exists(path.join(targetDir, 'package.json')))
215
+ ) {
216
+ await applyRepository(targetDir, repository);
217
+ }
218
+
188
219
  if (
189
220
  corePath !== undefined &&
190
221
  (await exists(path.join(targetDir, 'Cargo.toml')))
package/src/prompts.js CHANGED
@@ -72,6 +72,9 @@ export async function askAnswers(defaults, { interactive = true, derive } = {})
72
72
  'expected an npm package name, e.g. @vimp-games/space-arena',
73
73
  ),
74
74
  author: await ask('Author', defaults.author),
75
+ // пустой ответ допустим: поля repository тогда не будет вовсе, о чём
76
+ // скажет правило контракта A7
77
+ repository: await ask('Repository (URL or user/repo)', defaults.repository),
75
78
  };
76
79
  } finally {
77
80
  closePrompts();
@@ -1,4 +1,4 @@
1
1
  {
2
- "engine": "0.16.0",
2
+ "engine": "0.18.0",
3
3
  "core": "0.8.4"
4
4
  }
@@ -12,7 +12,6 @@ import { rangeToPattern } from './lib/rangeToPattern.js';
12
12
  // asset steps: it hashes what they produced.
13
13
  // Run: node scripts/build-game-manifest.js (build:manifest)
14
14
 
15
- const packageJsonPath = fileURLToPath(new URL('../package.json', import.meta.url));
16
15
  const distPath = fileURLToPath(new URL('../dist/', import.meta.url));
17
16
  const assetsPath = path.join(distPath, 'assets');
18
17
  const mapsPath = path.join(distPath, 'maps');
@@ -55,13 +54,6 @@ const version = createHash('sha256')
55
54
  .digest('hex')
56
55
  .slice(0, 16);
57
56
 
58
- // The npm version of this package. `version` above is a bundle hash — useful
59
- // to the engine, meaningless to a player; this is what the engine shows in
60
- // the #auth footer.
61
- const { version: packageVersion } = JSON.parse(
62
- fs.readFileSync(packageJsonPath, 'utf8'),
63
- );
64
-
65
57
  const mapNames = fs
66
58
  .readdirSync(mapsPath)
67
59
  .filter(name => name.endsWith('.json'))
@@ -163,7 +155,6 @@ const manifest = {
163
155
  id: '{{GAME_ID}}',
164
156
  engineApi: ENGINE_API_VERSION,
165
157
  version,
166
- packageVersion,
167
158
  title: '{{GAME_TITLE}}',
168
159
  entries: {
169
160
  client: `/games/{{GAME_ID}}/${clientFile}`,