create-projx 1.7.5 → 1.7.6

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.
@@ -8,8 +8,8 @@ import {
8
8
  matchesSkip,
9
9
  saveBaselineRef,
10
10
  writeTemplateToDir
11
- } from "./chunk-RFHLWYJ4.js";
12
- import "./chunk-B7PW6QO7.js";
11
+ } from "./chunk-NPBLDU4H.js";
12
+ import "./chunk-N66CVDEV.js";
13
13
  export {
14
14
  BASELINE_REF,
15
15
  applyTemplate,
@@ -26,6 +26,42 @@ var COMPONENTS = [
26
26
  "infra",
27
27
  "admin-panel"
28
28
  ];
29
+ function editDistance(a, b) {
30
+ const rows = a.length + 1;
31
+ const cols = b.length + 1;
32
+ const dist = Array.from(
33
+ { length: rows },
34
+ () => new Array(cols).fill(0)
35
+ );
36
+ for (let i = 0; i < rows; i++) dist[i][0] = i;
37
+ for (let j = 0; j < cols; j++) dist[0][j] = j;
38
+ for (let i = 1; i < rows; i++) {
39
+ for (let j = 1; j < cols; j++) {
40
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
41
+ dist[i][j] = Math.min(
42
+ dist[i - 1][j] + 1,
43
+ dist[i][j - 1] + 1,
44
+ dist[i - 1][j - 1] + cost
45
+ );
46
+ }
47
+ }
48
+ return dist[a.length][b.length];
49
+ }
50
+ function suggestComponent(input) {
51
+ const needle = input.toLowerCase();
52
+ let best = null;
53
+ let bestDistance = Infinity;
54
+ for (const c of COMPONENTS) {
55
+ const d = editDistance(needle, c);
56
+ if (d < bestDistance) {
57
+ bestDistance = d;
58
+ best = c;
59
+ }
60
+ }
61
+ if (best === null) return null;
62
+ const maxAllowed = Math.min(3, Math.floor(best.length / 2));
63
+ return bestDistance <= maxAllowed ? best : null;
64
+ }
29
65
  var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
30
66
  var ORM_PROVIDERS = [
31
67
  "prisma",
@@ -564,6 +600,7 @@ export {
564
600
  REPO,
565
601
  REPO_URL,
566
602
  COMPONENTS,
603
+ suggestComponent,
567
604
  PACKAGE_MANAGERS,
568
605
  ORM_PROVIDERS,
569
606
  pmCommands,
@@ -13,7 +13,7 @@ import {
13
13
  toSnake,
14
14
  upsertComponentMarker,
15
15
  writeProjxConfig
16
- } from "./chunk-B7PW6QO7.js";
16
+ } from "./chunk-N66CVDEV.js";
17
17
 
18
18
  // src/baseline.ts
19
19
  import { existsSync, writeFileSync, unlinkSync } from "fs";
@@ -128,7 +128,7 @@ function generateVscodeSettings(vars) {
128
128
  // src/baseline.ts
129
129
  var BASELINE_REF = "refs/projx/baseline";
130
130
  async function migrateComponentMarkers(cwd, components, componentPaths, applyDefaults) {
131
- const { readComponentMarker: readComponentMarker2, writeComponentMarker } = await import("./utils-X2P47QNN.js");
131
+ const { readComponentMarker: readComponentMarker2, writeComponentMarker } = await import("./utils-QQUKUZKQ.js");
132
132
  for (const component of components) {
133
133
  const dir = componentPaths[component];
134
134
  const markerDir = join2(cwd, dir);
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  matchesSkip,
10
10
  saveBaselineRef,
11
11
  writeTemplateToDir
12
- } from "./chunk-RFHLWYJ4.js";
12
+ } from "./chunk-NPBLDU4H.js";
13
13
  import {
14
14
  COMPONENTS,
15
15
  COMPONENT_MARKER,
@@ -32,11 +32,12 @@ import {
32
32
  readFileOrNull,
33
33
  readProjxConfig,
34
34
  render,
35
+ suggestComponent,
35
36
  toKebab,
36
37
  toSnake,
37
38
  writeComponentMarker,
38
39
  writeProjxConfig
39
- } from "./chunk-B7PW6QO7.js";
40
+ } from "./chunk-N66CVDEV.js";
40
41
 
41
42
  // src/index.ts
42
43
  import { existsSync as existsSync11 } from "fs";
@@ -902,7 +903,7 @@ function hasUncommittedChanges(cwd) {
902
903
  async function findPinnedFilesWithUpdates(cwd, repoDir, components, componentPaths, vars, version, componentSkips, rootSkip) {
903
904
  const { mkdtemp: mkdtemp2, rm: rm2, readFile: readFile8 } = await import("fs/promises");
904
905
  const { tmpdir: tmpdir2 } = await import("os");
905
- const { writeTemplateToDir: writeTemplateToDir2 } = await import("./baseline-O25CAKIL.js");
906
+ const { writeTemplateToDir: writeTemplateToDir2 } = await import("./baseline-2PBT5JBT.js");
906
907
  const config = await readProjxConfig(cwd);
907
908
  const rootPinned = Array.isArray(config.skip) ? config.skip : [];
908
909
  const componentPinned = [];
@@ -4228,7 +4229,20 @@ function parseArgs(argv = process.argv.slice(2)) {
4228
4229
  if (arg === "--components") {
4229
4230
  const val = args[++i];
4230
4231
  if (val) {
4231
- options.components = val.split(",").filter((c) => COMPONENTS.includes(c));
4232
+ const requested = val.split(",").map((c) => c.trim());
4233
+ const invalid = requested.filter(
4234
+ (c) => !COMPONENTS.includes(c)
4235
+ );
4236
+ if (invalid.length > 0) {
4237
+ const hints = invalid.map((c) => {
4238
+ const guess = suggestComponent(c);
4239
+ return guess ? `${c} (did you mean ${guess}?)` : c;
4240
+ }).join(", ");
4241
+ throw new Error(
4242
+ `Invalid --components: ${hints}. Available: ${COMPONENTS.join(", ")}`
4243
+ );
4244
+ }
4245
+ options.components = requested;
4232
4246
  }
4233
4247
  continue;
4234
4248
  }
@@ -4361,14 +4375,27 @@ async function main() {
4361
4375
  return;
4362
4376
  }
4363
4377
  if (command === "add") {
4364
- const components = extraArgs.filter(
4378
+ const positionals = extraArgs.filter((a) => !a.startsWith("-"));
4379
+ const components = positionals.filter(
4365
4380
  (c) => COMPONENTS.includes(c)
4366
4381
  );
4382
+ const unknown = positionals.filter(
4383
+ (c) => !COMPONENTS.includes(c)
4384
+ );
4385
+ if (unknown.length > 0) {
4386
+ for (const u of unknown) {
4387
+ const guess = suggestComponent(u);
4388
+ console.error(
4389
+ guess ? `Error: unknown component ${u} \u2014 did you mean ${guess}?` : `Error: unknown component ${u}. Available: ${COMPONENTS.join(", ")}`
4390
+ );
4391
+ }
4392
+ process.exit(2);
4393
+ }
4367
4394
  if (components.length === 0) {
4368
4395
  console.error(
4369
4396
  `Error: specify components to add. Available: ${COMPONENTS.join(", ")}`
4370
4397
  );
4371
- process.exit(1);
4398
+ process.exit(2);
4372
4399
  }
4373
4400
  const customName = extraArgs.find((a) => a.startsWith("--name="))?.slice("--name=".length);
4374
4401
  if (customName && components.length > 1) {
@@ -29,13 +29,14 @@ import {
29
29
  replaceInDir,
30
30
  replaceInFile,
31
31
  sharedTemplateDir,
32
+ suggestComponent,
32
33
  toKebab,
33
34
  toSnake,
34
35
  toTitle,
35
36
  upsertComponentMarker,
36
37
  writeComponentMarker,
37
38
  writeProjxConfig
38
- } from "./chunk-B7PW6QO7.js";
39
+ } from "./chunk-N66CVDEV.js";
39
40
  export {
40
41
  COMPONENTS,
41
42
  COMPONENT_MARKER,
@@ -67,6 +68,7 @@ export {
67
68
  replaceInDir,
68
69
  replaceInFile,
69
70
  sharedTemplateDir,
71
+ suggestComponent,
70
72
  toKebab,
71
73
  toSnake,
72
74
  toTitle,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-projx",
3
- "version": "1.7.5",
3
+ "version": "1.7.6",
4
4
  "description": "Scaffold production-grade fullstack projects in seconds. FastAPI, Fastify, Express, React, Flutter, Terraform — with auth, database, CI/CD, E2E tests, and Docker. One command, ready to deploy.",
5
5
  "type": "module",
6
6
  "bin": {