@amxts/cli 0.2.0 → 0.2.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@amxts/cli",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "description": "The amxts command: create a project or a module, add modules, build, deploy, type-check and test",
6
6
  "author": {
7
7
  "name": "kukson777",
@@ -17,7 +17,7 @@ import process from 'node:process';
17
17
  import { shortName, specFor } from './catalog.mjs';
18
18
  import { CLI_DIR, CORE_RANGE, FROM_SOURCE, needLocalCore } from './core.mjs';
19
19
  import { LINT_DEPENDENCIES, LINT_SCRIPTS } from './lint.mjs';
20
- import { detectPackageManager, execAmxts, installArgs, runScript } from './pm.mjs';
20
+ import { detectPackageManager, execAmxts, installArgs, runScript, testRunner } from './pm.mjs';
21
21
  import { copyTemplate, gitAuthor, writeFile } from './template.mjs';
22
22
  import { c, CliError, log } from './ui.mjs';
23
23
 
@@ -57,9 +57,11 @@ export async function initModule(options) {
57
57
  }
58
58
 
59
59
  const pm = options.pm ?? detectPackageManager();
60
+ const runner = testRunner(pm);
61
+ values['test.types'] = runner.types;
60
62
  const localCore = (options.local ?? FROM_SOURCE) ? await needLocalCore() : null;
61
63
 
62
- const written = copyTemplate(join(CLI_DIR, 'templates', 'module'), dir, values, { natives }, path => path === 'src/natives.ts' && !natives);
64
+ const written = copyTemplate(join(CLI_DIR, 'templates', 'module'), dir, values, { natives, bun: pm === 'bun' }, path => path === 'src/natives.ts' && !natives);
63
65
 
64
66
  const amxts = { module: 'src/index.ts' };
65
67
  if (natives) Object.assign(amxts, { natives: 'src/natives.ts', include: `include/${values.include}.inc` });
@@ -78,15 +80,15 @@ export async function initModule(options) {
78
80
  scripts: {
79
81
  build: 'amxts build',
80
82
  check: 'amxts check',
81
- test: 'amxts test',
83
+ test: runner.script,
82
84
  ...LINT_SCRIPTS,
83
85
  },
84
86
  peerDependencies: { '@amxts/core': CORE_RANGE },
85
87
  devDependencies: Object.fromEntries(Object.entries({
86
88
  ...(localCore ? { '@amxts/core': specFor({ name: '@amxts/core', dir: localCore.dir }, dir, pm) } : {}),
87
89
  ...LINT_DEPENDENCIES,
88
- '@types/bun': '^1.4.2',
89
- 'typescript': '^6.0.3',
90
+ ...runner.devDependencies,
91
+ typescript: '^6.0.3',
90
92
  }).sort(([a], [b]) => a.localeCompare(b))),
91
93
  }, null, '\t')}\n`);
92
94
  written.push('package.json');
package/src/init.mjs CHANGED
@@ -18,7 +18,7 @@ import { modulesList } from './config.mjs';
18
18
  import { bunFor, CLI_DIR, CORE_RANGE, coreDirFrom, FROM_SOURCE, loadCore, needLocalCore, readJson, VERSION } from './core.mjs';
19
19
  import { ensureIncludes, FETCHED, serverIncludes, targetOf, TARGETS } from './includes.mjs';
20
20
  import { LINT_DEPENDENCIES, LINT_FILES, LINT_SCRIPTS } from './lint.mjs';
21
- import { commandLine, execAmxts, installArgs, installLinked, linkedFolders, PACKAGE_MANAGERS, packageManagerOfAgent, run, runScript, versionOf } from './pm.mjs';
21
+ import { commandLine, execAmxts, installArgs, installLinked, linkedFolders, PACKAGE_MANAGERS, packageManagerOfAgent, run, runScript, testRunner, versionOf } from './pm.mjs';
22
22
  import { npmRegistry, versionsFor } from './registry.mjs';
23
23
  import { askServer, canAsk, missingServer, serverEnv, serverFolder } from './server.mjs';
24
24
  import { HOST_SYSTEM, serverSystemOf, SYSTEMS } from './system.mjs';
@@ -32,8 +32,7 @@ import { c, CliError } from './ui.mjs';
32
32
  * from this machine's folders (--local) are not called unused.
33
33
  */
34
34
  const TOOLS = {
35
- '@types/bun': '^1.4.2',
36
- 'knip': '^6.39.0',
35
+ knip: '^6.39.0',
37
36
  };
38
37
 
39
38
  const DEFAULT_DIR = 'my-server';
@@ -187,6 +186,7 @@ export async function initProject(options) {
187
186
  // The files.
188
187
  const amxts = execAmxts(pm);
189
188
  const install = installArgs(pm).join(' ');
189
+ const runner = testRunner(pm);
190
190
  const values = {
191
191
  'name': packageName(root),
192
192
  'author': gitAuthor(),
@@ -199,8 +199,9 @@ export async function initProject(options) {
199
199
  'run.typecheck': runScript(pm, 'typecheck'),
200
200
  'run.test': runScript(pm, 'test'),
201
201
  'run.lint': runScript(pm, 'lint'),
202
+ 'test.types': runner.types,
202
203
  };
203
- const flags = { lint, ...Object.fromEntries(installed.map(module => [shortName(module.name), true])) };
204
+ const flags = { lint, bun: pm === 'bun', ...Object.fromEntries(installed.map(module => [shortName(module.name), true])) };
204
205
  const written = copyTemplate(join(CLI_DIR, 'templates', 'project'), root, values, flags, path => LINT_FILES.includes(path) && !lint);
205
206
 
206
207
  const core = { name: '@amxts/core', dir: localCore?.dir ?? null };
@@ -209,6 +210,7 @@ export async function initProject(options) {
209
210
  [core.name]: specFor(core, root, pm, CORE_RANGE),
210
211
  ...Object.fromEntries(installed.map(module => [module.name, specFor(module, root, pm, versions[module.name] ? `^${versions[module.name]}` : 'latest')])),
211
212
  ...TOOLS,
213
+ ...runner.devDependencies,
212
214
  ...(lint ? LINT_DEPENDENCIES : {}),
213
215
  };
214
216
  writeFile(join(root, 'package.json'), `${JSON.stringify({
@@ -221,7 +223,7 @@ export async function initProject(options) {
221
223
  dev: 'amxts dev',
222
224
  build: 'amxts build',
223
225
  typecheck: 'amxts typecheck',
224
- test: 'amxts test',
226
+ test: runner.script,
225
227
  ...(lint ? LINT_SCRIPTS : {}),
226
228
  },
227
229
  devDependencies: Object.fromEntries(Object.entries(devDependencies).sort(([a], [b]) => a.localeCompare(b))),
package/src/main.mjs CHANGED
@@ -6,7 +6,9 @@
6
6
  // It runs on Node. Commands that make or change a project (init, module,
7
7
  // info) run here; the ones that compile (build, dev, typecheck, check,
8
8
  // prepare) are tasks of the project's core, which runs them on Bun
9
- // (core.mjs); test runs bun test.
9
+ // (core.mjs); test runs the project's Vitest, or bun test.
10
+ import { existsSync } from 'node:fs';
11
+ import { join } from 'node:path';
10
12
  import process from 'node:process';
11
13
  import { GLOBAL_FLAGS, parseArgs } from './args.mjs';
12
14
  import { needBun, needProject, projectCore, runTask, runTaskOrExit, VERSION } from './core.mjs';
@@ -137,12 +139,17 @@ export const COMMANDS = {
137
139
  },
138
140
  },
139
141
  test: {
140
- description: 'Run the project\'s tests on a fake server (bun test)',
141
- usage: 'amxts test [bun test options]',
142
+ description: 'Run the project\'s tests on a fake server (Vitest when the project has it, else bun test)',
143
+ usage: 'amxts test [test runner options]',
142
144
  passThrough: true,
143
145
  examples: ['amxts test', 'amxts test hello', 'amxts test --watch'],
144
146
  async run({ raw }) {
145
- const result = await run([needBun(await projectCore(), 'runs tests'), 'test', ...raw]);
147
+ const core = await projectCore();
148
+ // A project with Vitest tests on Node; any other on bun test.
149
+ const vitest = join(needProject(), 'node_modules', 'vitest', 'vitest.mjs');
150
+ const result = await run(existsSync(vitest)
151
+ ? [process.execPath, vitest, ...(raw.includes('--watch') ? [] : ['run']), ...raw]
152
+ : [needBun(core, 'runs tests'), 'test', ...raw]);
146
153
  process.exitCode = result.code;
147
154
  },
148
155
  },
package/src/pm.mjs CHANGED
@@ -75,6 +75,17 @@ export function execAmxts(pm) {
75
75
  return { npm: 'npx amxts', pnpm: 'pnpm amxts', yarn: 'yarn amxts', bun: 'bunx amxts' }[pm] ?? 'npx amxts';
76
76
  }
77
77
 
78
+ /**
79
+ * What a new project's or module's tests run on: `bun test` with Bun as the
80
+ * package manager, Vitest on Node with any other. `types` is the test
81
+ * folder's tsconfig `types`.
82
+ */
83
+ export function testRunner(pm) {
84
+ return pm === 'bun'
85
+ ? { script: 'amxts test', types: 'bun', devDependencies: { '@types/bun': '^1.4.2' } }
86
+ : { script: 'vitest run', types: 'node', devDependencies: { '@types/node': '^24.0.0', 'vitest': '^5.0.3' } };
87
+ }
88
+
78
89
  /**
79
90
  * The folders a project's package.json takes packages from - `link:` and
80
91
  * `file:` specs: the core and the modules of this machine (--local).
@@ -4,7 +4,7 @@
4
4
  "lib": ["ES2022"],
5
5
  "module": "ESNext",
6
6
  "moduleResolution": "bundler",
7
- "types": ["bun"],
7
+ "types": ["{{test.types}}"],
8
8
  "strict": true,
9
9
  "noEmit": true,
10
10
  "skipLibCheck": true
@@ -1,4 +1,9 @@
1
+ // #if bun
1
2
  import { describe, expect, test } from "bun:test";
3
+ // #endif
4
+ // #if !bun
5
+ import { describe, expect, test } from "vitest";
6
+ // #endif
2
7
  import { setup } from "@amxts/core/test-utils";
3
8
 
4
9
  // The first test compiles the plugins; the next runs take them from the cache.
@@ -1,11 +1,21 @@
1
+ // #if bun
1
2
  import { expect, setDefaultTimeout, test } from "bun:test";
3
+ // #endif
4
+ // #if !bun
5
+ import { expect, test, vi } from "vitest";
6
+ // #endif
2
7
  import { setup } from "@amxts/core/test-utils";
3
8
  // #if menu-core
4
9
  import { menusOf } from "@amxts/menu-core/testing";
5
10
  // #endif
6
11
 
7
12
  // The first run compiles the plugins; the next ones take them from the cache.
13
+ // #if bun
8
14
  setDefaultTimeout(120_000);
15
+ // #endif
16
+ // #if !bun
17
+ vi.setConfig({ testTimeout: 120_000 });
18
+ // #endif
9
19
 
10
20
  test("a player who joins is greeted", async () => {
11
21
  const server = await setup();
@@ -4,7 +4,7 @@
4
4
  "lib": ["ES2022"],
5
5
  "module": "ESNext",
6
6
  "moduleResolution": "bundler",
7
- "types": ["bun"],
7
+ "types": ["{{test.types}}"],
8
8
  "strict": true,
9
9
  "noEmit": true,
10
10
  "skipLibCheck": true