@toolstackhq/create-qa-patterns 1.0.2 → 1.0.3

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.
Files changed (3) hide show
  1. package/README.md +9 -0
  2. package/index.js +99 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -41,3 +41,12 @@ When run in a terminal, the CLI shows:
41
41
  - `npm install`
42
42
  - `npx playwright install`
43
43
  - `npm test`
44
+
45
+ ## Prerequisite checks
46
+
47
+ The CLI checks:
48
+
49
+ - required Node.js version
50
+ - `npm` availability for install and test actions
51
+ - `npx` availability for Playwright browser installation
52
+ - `docker` availability and warns if it is missing
package/index.js CHANGED
@@ -3,9 +3,14 @@
3
3
  const fs = require("node:fs");
4
4
  const path = require("node:path");
5
5
  const readline = require("node:readline");
6
- const { spawn } = require("node:child_process");
6
+ const { spawn, spawnSync } = require("node:child_process");
7
7
 
8
8
  const DEFAULT_TEMPLATE = "playwright-template";
9
+ const MIN_NODE_VERSION = {
10
+ major: 18,
11
+ minor: 18,
12
+ patch: 0
13
+ };
9
14
  const DEFAULT_GITIGNORE = `node_modules/
10
15
 
11
16
  .env
@@ -53,6 +58,39 @@ Supported templates:
53
58
  `);
54
59
  }
55
60
 
61
+ function parseNodeVersion(version) {
62
+ const normalized = version.replace(/^v/, "");
63
+ const [major = "0", minor = "0", patch = "0"] = normalized.split(".");
64
+
65
+ return {
66
+ major: Number.parseInt(major, 10),
67
+ minor: Number.parseInt(minor, 10),
68
+ patch: Number.parseInt(patch, 10)
69
+ };
70
+ }
71
+
72
+ function isNodeVersionSupported(version) {
73
+ if (version.major !== MIN_NODE_VERSION.major) {
74
+ return version.major > MIN_NODE_VERSION.major;
75
+ }
76
+
77
+ if (version.minor !== MIN_NODE_VERSION.minor) {
78
+ return version.minor > MIN_NODE_VERSION.minor;
79
+ }
80
+
81
+ return version.patch >= MIN_NODE_VERSION.patch;
82
+ }
83
+
84
+ function assertSupportedNodeVersion() {
85
+ const currentVersion = parseNodeVersion(process.version);
86
+
87
+ if (!isNodeVersionSupported(currentVersion)) {
88
+ throw new Error(
89
+ `Node ${MIN_NODE_VERSION.major}.${MIN_NODE_VERSION.minor}.${MIN_NODE_VERSION.patch}+ is required. Current version: ${process.version}`
90
+ );
91
+ }
92
+ }
93
+
56
94
  function resolveTemplate(value) {
57
95
  return TEMPLATE_ALIASES.get(value);
58
96
  }
@@ -65,6 +103,40 @@ function sleep(ms) {
65
103
  return new Promise((resolve) => setTimeout(resolve, ms));
66
104
  }
67
105
 
106
+ function commandExists(command) {
107
+ const result = spawnSync(getCommandName(command), ["--version"], {
108
+ stdio: "ignore"
109
+ });
110
+
111
+ return !result.error && result.status === 0;
112
+ }
113
+
114
+ function collectPrerequisites() {
115
+ return {
116
+ npm: commandExists("npm"),
117
+ npx: commandExists("npx"),
118
+ docker: commandExists("docker")
119
+ };
120
+ }
121
+
122
+ function printPrerequisiteWarnings(prerequisites) {
123
+ if (!prerequisites.npm) {
124
+ process.stdout.write("Warning: npm was not found. Automated install and test steps will be unavailable.\n");
125
+ }
126
+
127
+ if (!prerequisites.npx) {
128
+ process.stdout.write("Warning: npx was not found. Playwright browser installation will be unavailable.\n");
129
+ }
130
+
131
+ if (!prerequisites.docker) {
132
+ process.stdout.write("Warning: docker was not found. Docker-based template flows will not run until Docker is installed.\n");
133
+ }
134
+
135
+ if (!prerequisites.npm || !prerequisites.npx || !prerequisites.docker) {
136
+ process.stdout.write("\n");
137
+ }
138
+ }
139
+
68
140
  function createLineInterface() {
69
141
  return readline.createInterface({
70
142
  input: process.stdin,
@@ -421,34 +493,51 @@ async function runPostGenerateActions(targetDirectory) {
421
493
  return;
422
494
  }
423
495
 
424
- const shouldInstallDependencies = await askYesNo("Run npm install now?", true);
496
+ const prerequisites = collectPrerequisites();
497
+
498
+ if (prerequisites.npm) {
499
+ const shouldInstallDependencies = await askYesNo("Run npm install now?", true);
425
500
 
426
- if (shouldInstallDependencies) {
427
- await runCommand("npm", ["install"], targetDirectory);
501
+ if (shouldInstallDependencies) {
502
+ await runCommand("npm", ["install"], targetDirectory);
503
+ }
504
+ } else {
505
+ process.stdout.write("Skipping npm install prompt because npm is not available.\n");
428
506
  }
429
507
 
430
- const shouldInstallPlaywright = await askYesNo("Run npx playwright install now?", true);
508
+ if (prerequisites.npx) {
509
+ const shouldInstallPlaywright = await askYesNo("Run npx playwright install now?", true);
431
510
 
432
- if (shouldInstallPlaywright) {
433
- await runCommand("npx", ["playwright", "install"], targetDirectory);
511
+ if (shouldInstallPlaywright) {
512
+ await runCommand("npx", ["playwright", "install"], targetDirectory);
513
+ }
514
+ } else {
515
+ process.stdout.write("Skipping Playwright browser install prompt because npx is not available.\n");
434
516
  }
435
517
 
436
- const shouldRunTests = await askYesNo("Run npm test now?", false);
518
+ if (prerequisites.npm) {
519
+ const shouldRunTests = await askYesNo("Run npm test now?", false);
437
520
 
438
- if (shouldRunTests) {
439
- await runCommand("npm", ["test"], targetDirectory);
521
+ if (shouldRunTests) {
522
+ await runCommand("npm", ["test"], targetDirectory);
523
+ }
524
+ } else {
525
+ process.stdout.write("Skipping npm test prompt because npm is not available.\n");
440
526
  }
441
527
  }
442
528
 
443
529
  async function main() {
444
530
  const args = process.argv.slice(2);
445
531
 
532
+ assertSupportedNodeVersion();
533
+
446
534
  if (args.includes("--help") || args.includes("-h")) {
447
535
  printHelp();
448
536
  return;
449
537
  }
450
538
 
451
539
  const { templateName, targetDirectory, generatedInCurrentDirectory } = await resolveScaffoldArgs(args);
540
+ printPrerequisiteWarnings(collectPrerequisites());
452
541
  await scaffoldProject(templateName, targetDirectory);
453
542
  printSuccess(templateName, targetDirectory, generatedInCurrentDirectory);
454
543
  await runPostGenerateActions(targetDirectory);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolstackhq/create-qa-patterns",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "CLI for generating QA framework templates.",
5
5
  "license": "MIT",
6
6
  "repository": {