create-projx 1.5.5 → 1.5.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.
@@ -0,0 +1,70 @@
1
+ import {
2
+ COMPONENTS,
3
+ COMPONENT_MARKER,
4
+ DEFAULT_COMPONENT_SKIP_PATTERNS,
5
+ DEFAULT_ROOT_SKIP_PATTERNS,
6
+ EXCLUDE,
7
+ PACKAGE_MANAGERS,
8
+ REPO,
9
+ REPO_URL,
10
+ cleanupRepo,
11
+ copyComponent,
12
+ copyStaticFiles,
13
+ detectPackageManager,
14
+ detectPackageManagerFromComponents,
15
+ detectProjectName,
16
+ discoverComponentPaths,
17
+ discoverComponentsFromMarkers,
18
+ downloadRepo,
19
+ exec,
20
+ hasCommand,
21
+ pmCommands,
22
+ readComponentMarker,
23
+ readFileOrNull,
24
+ readProjxConfig,
25
+ render,
26
+ replaceInDir,
27
+ replaceInFile,
28
+ sharedTemplateDir,
29
+ toKebab,
30
+ toSnake,
31
+ toTitle,
32
+ upsertComponentMarker,
33
+ writeComponentMarker,
34
+ writeProjxConfig
35
+ } from "./chunk-FTHX7ILT.js";
36
+ export {
37
+ COMPONENTS,
38
+ COMPONENT_MARKER,
39
+ DEFAULT_COMPONENT_SKIP_PATTERNS,
40
+ DEFAULT_ROOT_SKIP_PATTERNS,
41
+ EXCLUDE,
42
+ PACKAGE_MANAGERS,
43
+ REPO,
44
+ REPO_URL,
45
+ cleanupRepo,
46
+ copyComponent,
47
+ copyStaticFiles,
48
+ detectPackageManager,
49
+ detectPackageManagerFromComponents,
50
+ detectProjectName,
51
+ discoverComponentPaths,
52
+ discoverComponentsFromMarkers,
53
+ downloadRepo,
54
+ exec,
55
+ hasCommand,
56
+ pmCommands,
57
+ readComponentMarker,
58
+ readFileOrNull,
59
+ readProjxConfig,
60
+ render,
61
+ replaceInDir,
62
+ replaceInFile,
63
+ sharedTemplateDir,
64
+ toKebab,
65
+ toSnake,
66
+ toTitle,
67
+ upsertComponentMarker,
68
+ writeComponentMarker,
69
+ writeProjxConfig
70
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-projx",
3
- "version": "1.5.5",
3
+ "version": "1.5.6",
4
4
  "description": "Scaffold production-grade fullstack projects in seconds. FastAPI, Fastify, React, Flutter, Terraform — with auth, database, CI/CD, E2E tests, and Docker. One command, ready to deploy.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,22 +7,22 @@ Scaffolded with [Projx](https://github.com/ukanhaupa/projx).
7
7
  | Layer | Technology |
8
8
  | ----- | ---------- |
9
9
  <% if (components.includes('fastapi')) { %>
10
- | **Backend (Python)** | FastAPI, SQLAlchemy, Alembic, uvicorn |
10
+ | **<%= paths.fastapi %>/** | FastAPI, SQLAlchemy, Alembic, uvicorn |
11
11
  <% } %>
12
12
  <% if (components.includes('fastify')) { %>
13
- | **Backend (Node)** | Fastify, Prisma, TypeBox, TypeScript |
13
+ | **<%= paths.fastify %>/** | Fastify, Prisma, TypeBox, TypeScript |
14
14
  <% } %>
15
15
  <% if (components.includes('frontend')) { %>
16
- | **Frontend** | React 19, TypeScript, Vite, React Router |
16
+ | **<%= paths.frontend %>/** | React 19, TypeScript, Vite, React Router |
17
17
  <% } %>
18
18
  <% if (components.includes('mobile')) { %>
19
- | **Mobile** | Flutter, Dart, Riverpod, GoRouter, Isar |
19
+ | **<%= paths.mobile %>/** | Flutter, Dart, Riverpod, GoRouter, Isar |
20
20
  <% } %>
21
21
  <% if (components.includes('e2e')) { %>
22
- | **E2E Tests** | Playwright |
22
+ | **<%= paths.e2e %>/** | Playwright |
23
23
  <% } %>
24
24
  <% if (components.includes('infra')) { %>
25
- | **Infrastructure** | Terraform, AWS (EKS, RDS, VPC, CodePipeline) |
25
+ | **<%= paths.infra %>/** | Terraform, AWS (EKS, RDS, VPC, CodePipeline) |
26
26
  <% } %>
27
27
  | **Identity** | Keycloak (OIDC / JWT) |
28
28
  | **Containers** | Docker, Docker Compose |
@@ -35,7 +35,7 @@ docker compose -f docker-compose.dev.yml up # Start with Docker (dev mode)
35
35
  ```
36
36
  <% if (components.includes('fastapi')) { %>
37
37
 
38
- ### FastAPI
38
+ ### <%= paths.fastapi %>/
39
39
 
40
40
  ```bash
41
41
  cd <%= paths.fastapi %> && cp .env.example .env && uv sync && uv run main.py
@@ -45,7 +45,7 @@ API docs at `http://localhost:7860/docs`.
45
45
  <% } %>
46
46
  <% if (components.includes('fastify')) { %>
47
47
 
48
- ### Fastify
48
+ ### <%= paths.fastify %>/
49
49
 
50
50
  ```bash
51
51
  cd <%= paths.fastify %> && cp .env.example .env && <%= pm.install %> && <%= pm.exec %> prisma migrate dev && <%= pm.run %> dev
@@ -55,7 +55,7 @@ API docs at `http://localhost:3000/docs`.
55
55
  <% } %>
56
56
  <% if (components.includes('frontend')) { %>
57
57
 
58
- ### Frontend
58
+ ### <%= paths.frontend %>/
59
59
 
60
60
  ```bash
61
61
  cd <%= paths.frontend %> && cp .env.example .env && <%= pm.install %> && <%= pm.run %> dev
@@ -63,7 +63,7 @@ cd <%= paths.frontend %> && cp .env.example .env && <%= pm.install %> && <%= pm.
63
63
  <% } %>
64
64
  <% if (components.includes('mobile')) { %>
65
65
 
66
- ### Mobile
66
+ ### <%= paths.mobile %>/
67
67
 
68
68
  ```bash
69
69
  cd <%= paths.mobile %> && cp .env.example .env && flutter pub get && flutter run
@@ -14,22 +14,22 @@ jobs:
14
14
  pull-requests: read
15
15
  outputs:
16
16
  <% if (components.includes('fastapi')) { %>
17
- fastapi: ${{ steps.filter.outputs.<%= paths.fastapi %> }}
17
+ <%= paths.fastapi %>: ${{ steps.filter.outputs.<%= paths.fastapi %> }}
18
18
  <% } %>
19
19
  <% if (components.includes('fastify')) { %>
20
- fastify: ${{ steps.filter.outputs.<%= paths.fastify %> }}
20
+ <%= paths.fastify %>: ${{ steps.filter.outputs.<%= paths.fastify %> }}
21
21
  <% } %>
22
22
  <% if (components.includes('frontend')) { %>
23
- frontend: ${{ steps.filter.outputs.<%= paths.frontend %> }}
23
+ <%= paths.frontend %>: ${{ steps.filter.outputs.<%= paths.frontend %> }}
24
24
  <% } %>
25
25
  <% if (components.includes('mobile')) { %>
26
- mobile: ${{ steps.filter.outputs.<%= paths.mobile %> }}
26
+ <%= paths.mobile %>: ${{ steps.filter.outputs.<%= paths.mobile %> }}
27
27
  <% } %>
28
28
  <% if (components.includes('e2e')) { %>
29
- e2e: ${{ steps.filter.outputs.<%= paths.e2e %> }}
29
+ <%= paths.e2e %>: ${{ steps.filter.outputs.<%= paths.e2e %> }}
30
30
  <% } %>
31
31
  <% if (components.includes('infra')) { %>
32
- infra: ${{ steps.filter.outputs.<%= paths.infra %> }}
32
+ <%= paths.infra %>: ${{ steps.filter.outputs.<%= paths.infra %> }}
33
33
  <% } %>
34
34
  steps:
35
35
  - uses: actions/checkout@v5
@@ -63,10 +63,10 @@ jobs:
63
63
  <% } %>
64
64
  <% if (components.includes('fastapi')) { %>
65
65
 
66
- fastapi:
67
- name: FastAPI (format + lint)
66
+ <%= paths.fastapi %>:
67
+ name: <%= displayNames.fastapi %> (format + lint)
68
68
  needs: changes
69
- if: needs.changes.outputs.fastapi == 'true'
69
+ if: needs.changes.outputs.<%= paths.fastapi %> == 'true'
70
70
  runs-on: ubuntu-latest
71
71
  defaults:
72
72
  run:
@@ -80,10 +80,10 @@ jobs:
80
80
  <% } %>
81
81
  <% if (components.includes('fastify')) { %>
82
82
 
83
- fastify:
84
- name: Fastify (format + lint + typecheck)
83
+ <%= paths.fastify %>:
84
+ name: <%= displayNames.fastify %> (format + lint + typecheck)
85
85
  needs: changes
86
- if: needs.changes.outputs.fastify == 'true'
86
+ if: needs.changes.outputs.<%= paths.fastify %> == 'true'
87
87
  runs-on: ubuntu-latest
88
88
  defaults:
89
89
  run:
@@ -113,10 +113,10 @@ jobs:
113
113
  <% } %>
114
114
  <% if (components.includes('frontend')) { %>
115
115
 
116
- frontend:
117
- name: Frontend (format + lint + typecheck)
116
+ <%= paths.frontend %>:
117
+ name: <%= displayNames.frontend %> (format + lint + typecheck)
118
118
  needs: changes
119
- if: needs.changes.outputs.frontend == 'true'
119
+ if: needs.changes.outputs.<%= paths.frontend %> == 'true'
120
120
  runs-on: ubuntu-latest
121
121
  defaults:
122
122
  run:
@@ -145,10 +145,10 @@ jobs:
145
145
  <% } %>
146
146
  <% if (components.includes('mobile')) { %>
147
147
 
148
- mobile:
149
- name: Flutter (format + analyze)
148
+ <%= paths.mobile %>:
149
+ name: <%= displayNames.mobile %> (format + analyze)
150
150
  needs: changes
151
- if: needs.changes.outputs.mobile == 'true'
151
+ if: needs.changes.outputs.<%= paths.mobile %> == 'true'
152
152
  runs-on: ubuntu-latest
153
153
  defaults:
154
154
  run:
@@ -165,10 +165,10 @@ jobs:
165
165
  <% } %>
166
166
  <% if (components.includes('e2e')) { %>
167
167
 
168
- e2e:
169
- name: E2E (format + lint + typecheck)
168
+ <%= paths.e2e %>:
169
+ name: <%= displayNames.e2e %> (format + lint + typecheck)
170
170
  needs: changes
171
- if: needs.changes.outputs.e2e == 'true'
171
+ if: needs.changes.outputs.<%= paths.e2e %> == 'true'
172
172
  runs-on: ubuntu-latest
173
173
  defaults:
174
174
  run:
@@ -197,10 +197,10 @@ jobs:
197
197
  <% } %>
198
198
  <% if (components.includes('infra')) { %>
199
199
 
200
- infra:
201
- name: Terraform (fmt + validate)
200
+ <%= paths.infra %>:
201
+ name: <%= displayNames.infra %> (fmt + validate)
202
202
  needs: changes
203
- if: needs.changes.outputs.infra == 'true'
203
+ if: needs.changes.outputs.<%= paths.infra %> == 'true'
204
204
  runs-on: ubuntu-latest
205
205
  defaults:
206
206
  run:
@@ -134,12 +134,8 @@ services:
134
134
  command: sh -c "<%= pm.install %> && <%= pm.run %> dev -- --host 0.0.0.0"
135
135
  ports:
136
136
  - '5173:5173'
137
- environment:
138
- <% if (components.includes('fastify')) { %>
139
- - VITE_API_URL=http://localhost:3000
140
- <% } else if (components.includes('fastapi')) { %>
141
- - VITE_API_URL=http://localhost:7860
142
- <% } %>
137
+ env_file:
138
+ - ./<%= paths.frontend %>/.env
143
139
  volumes:
144
140
  - ./<%= paths.frontend %>:/app
145
141
  - frontend_node_modules:/app/node_modules
@@ -29,77 +29,77 @@ fi
29
29
  STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
30
30
  <% if (components.includes('fastapi')) { %>
31
31
 
32
- FASTAPI_PY=$(echo "$STAGED_FILES" | grep '^<%= paths.fastapi %>/.*\.py$' || true)
33
- if [ -n "$FASTAPI_PY" ]; then
32
+ <%= pathsUpper.fastapi %>_PY=$(echo "$STAGED_FILES" | grep '^<%= paths.fastapi %>/.*\.py$' || true)
33
+ if [ -n "$<%= pathsUpper.fastapi %>_PY" ]; then
34
34
  echo "Formatting & linting <%= paths.fastapi %>..."
35
35
  cd <%= paths.fastapi %>
36
- echo "$FASTAPI_PY" | sed 's|^<%= paths.fastapi %>/||' | xargs uv run ruff format
37
- echo "$FASTAPI_PY" | sed 's|^<%= paths.fastapi %>/||' | xargs uv run ruff check --fix
36
+ echo "$<%= pathsUpper.fastapi %>_PY" | sed 's|^<%= paths.fastapi %>/||' | xargs uv run ruff format
37
+ echo "$<%= pathsUpper.fastapi %>_PY" | sed 's|^<%= paths.fastapi %>/||' | xargs uv run ruff check --fix
38
38
  cd ..
39
- echo "$FASTAPI_PY" | xargs git add
39
+ echo "$<%= pathsUpper.fastapi %>_PY" | xargs git add
40
40
  fi
41
41
  <% } %>
42
42
  <% if (components.includes('fastify')) { %>
43
43
 
44
- FASTIFY_TS=$(echo "$STAGED_FILES" | grep '^<%= paths.fastify %>/.*\.ts$' || true)
45
- FASTIFY_ALL=$(echo "$STAGED_FILES" | grep '^<%= paths.fastify %>/' || true)
46
- if [ -n "$FASTIFY_ALL" ]; then
44
+ <%= pathsUpper.fastify %>_TS=$(echo "$STAGED_FILES" | grep '^<%= paths.fastify %>/.*\.ts$' || true)
45
+ <%= pathsUpper.fastify %>_ALL=$(echo "$STAGED_FILES" | grep '^<%= paths.fastify %>/' || true)
46
+ if [ -n "$<%= pathsUpper.fastify %>_ALL" ]; then
47
47
  echo "Formatting <%= paths.fastify %>..."
48
48
  cd <%= paths.fastify %>
49
- echo "$FASTIFY_ALL" | sed 's|^<%= paths.fastify %>/||' | xargs <%= pm.exec %> prettier --write --ignore-unknown
50
- if [ -n "$FASTIFY_TS" ]; then
51
- echo "$FASTIFY_TS" | sed 's|^<%= paths.fastify %>/||' | xargs <%= pm.exec %> eslint --fix
49
+ echo "$<%= pathsUpper.fastify %>_ALL" | sed 's|^<%= paths.fastify %>/||' | xargs <%= pm.exec %> prettier --write --ignore-unknown
50
+ if [ -n "$<%= pathsUpper.fastify %>_TS" ]; then
51
+ echo "$<%= pathsUpper.fastify %>_TS" | sed 's|^<%= paths.fastify %>/||' | xargs <%= pm.exec %> eslint --fix
52
52
  <%= pm.exec %> tsc --noEmit
53
53
  fi
54
54
  cd ..
55
- echo "$FASTIFY_ALL" | xargs git add
55
+ echo "$<%= pathsUpper.fastify %>_ALL" | xargs git add
56
56
  fi
57
57
  <% } %>
58
58
  <% if (components.includes('frontend')) { %>
59
59
 
60
- FRONTEND_TS=$(echo "$STAGED_FILES" | grep '^<%= paths.frontend %>/.*\.tsx\?$' || true)
61
- FRONTEND_ALL=$(echo "$STAGED_FILES" | grep '^<%= paths.frontend %>/' || true)
62
- if [ -n "$FRONTEND_ALL" ]; then
60
+ <%= pathsUpper.frontend %>_TS=$(echo "$STAGED_FILES" | grep '^<%= paths.frontend %>/.*\.tsx\?$' || true)
61
+ <%= pathsUpper.frontend %>_ALL=$(echo "$STAGED_FILES" | grep '^<%= paths.frontend %>/' || true)
62
+ if [ -n "$<%= pathsUpper.frontend %>_ALL" ]; then
63
63
  echo "Formatting <%= paths.frontend %>..."
64
64
  cd <%= paths.frontend %>
65
- echo "$FRONTEND_ALL" | sed 's|^<%= paths.frontend %>/||' | xargs <%= pm.exec %> prettier --write --ignore-unknown
66
- if [ -n "$FRONTEND_TS" ]; then
67
- echo "$FRONTEND_TS" | sed 's|^<%= paths.frontend %>/||' | xargs <%= pm.exec %> eslint --fix
65
+ echo "$<%= pathsUpper.frontend %>_ALL" | sed 's|^<%= paths.frontend %>/||' | xargs <%= pm.exec %> prettier --write --ignore-unknown
66
+ if [ -n "$<%= pathsUpper.frontend %>_TS" ]; then
67
+ echo "$<%= pathsUpper.frontend %>_TS" | sed 's|^<%= paths.frontend %>/||' | xargs <%= pm.exec %> eslint --fix
68
68
  <%= pm.exec %> tsc --noEmit
69
69
  fi
70
70
  cd ..
71
- echo "$FRONTEND_ALL" | xargs git add
71
+ echo "$<%= pathsUpper.frontend %>_ALL" | xargs git add
72
72
  fi
73
73
  <% } %>
74
74
  <% if (components.includes('e2e')) { %>
75
75
 
76
- E2E_TS=$(echo "$STAGED_FILES" | grep '^<%= paths.e2e %>/.*\.ts$' || true)
77
- E2E_ALL=$(echo "$STAGED_FILES" | grep '^<%= paths.e2e %>/' || true)
78
- if [ -n "$E2E_ALL" ]; then
76
+ <%= pathsUpper.e2e %>_TS=$(echo "$STAGED_FILES" | grep '^<%= paths.e2e %>/.*\.ts$' || true)
77
+ <%= pathsUpper.e2e %>_ALL=$(echo "$STAGED_FILES" | grep '^<%= paths.e2e %>/' || true)
78
+ if [ -n "$<%= pathsUpper.e2e %>_ALL" ]; then
79
79
  echo "Formatting <%= paths.e2e %>..."
80
80
  cd <%= paths.e2e %>
81
- echo "$E2E_ALL" | sed 's|^<%= paths.e2e %>/||' | xargs <%= pm.exec %> prettier --write --ignore-unknown
82
- if [ -n "$E2E_TS" ]; then
83
- echo "$E2E_TS" | sed 's|^<%= paths.e2e %>/||' | xargs <%= pm.exec %> eslint --fix
81
+ echo "$<%= pathsUpper.e2e %>_ALL" | sed 's|^<%= paths.e2e %>/||' | xargs <%= pm.exec %> prettier --write --ignore-unknown
82
+ if [ -n "$<%= pathsUpper.e2e %>_TS" ]; then
83
+ echo "$<%= pathsUpper.e2e %>_TS" | sed 's|^<%= paths.e2e %>/||' | xargs <%= pm.exec %> eslint --fix
84
84
  <%= pm.exec %> tsc --noEmit
85
85
  fi
86
86
  cd ..
87
- echo "$E2E_ALL" | xargs git add
87
+ echo "$<%= pathsUpper.e2e %>_ALL" | xargs git add
88
88
  fi
89
89
  <% } %>
90
90
  <% if (components.includes('mobile')) { %>
91
91
 
92
- MOBILE_DART=$(echo "$STAGED_FILES" | grep '^<%= paths.mobile %>/.*\.dart$' || true)
93
- if [ -n "$MOBILE_DART" ]; then
92
+ <%= pathsUpper.mobile %>_DART=$(echo "$STAGED_FILES" | grep '^<%= paths.mobile %>/.*\.dart$' || true)
93
+ if [ -n "$<%= pathsUpper.mobile %>_DART" ]; then
94
94
  if command -v dart &> /dev/null; then
95
95
  echo "Formatting <%= paths.mobile %>..."
96
96
  cd <%= paths.mobile %>
97
- echo "$MOBILE_DART" | sed 's|^<%= paths.mobile %>/||' | xargs dart format
97
+ echo "$<%= pathsUpper.mobile %>_DART" | sed 's|^<%= paths.mobile %>/||' | xargs dart format
98
98
  if command -v flutter &> /dev/null; then
99
99
  dart analyze --fatal-infos
100
100
  fi
101
101
  cd ..
102
- echo "$MOBILE_DART" | xargs git add
102
+ echo "$<%= pathsUpper.mobile %>_DART" | xargs git add
103
103
  else
104
104
  echo "Skipping mobile lint (dart not installed)"
105
105
  fi
@@ -107,14 +107,14 @@ fi
107
107
  <% } %>
108
108
  <% if (components.includes('infra')) { %>
109
109
 
110
- INFRA_TF=$(echo "$STAGED_FILES" | grep '^<%= paths.infra %>/.*\.tf$' || true)
111
- if [ -n "$INFRA_TF" ]; then
110
+ <%= pathsUpper.infra %>_TF=$(echo "$STAGED_FILES" | grep '^<%= paths.infra %>/.*\.tf$' || true)
111
+ if [ -n "$<%= pathsUpper.infra %>_TF" ]; then
112
112
  if command -v terraform &> /dev/null; then
113
113
  echo "Formatting <%= paths.infra %>..."
114
114
  cd <%= paths.infra %>/stack
115
- echo "$INFRA_TF" | sed 's|^<%= paths.infra %>/stack/||' | xargs terraform fmt
115
+ echo "$<%= pathsUpper.infra %>_TF" | sed 's|^<%= paths.infra %>/stack/||' | xargs terraform fmt
116
116
  cd ../..
117
- echo "$INFRA_TF" | xargs git add
117
+ echo "$<%= pathsUpper.infra %>_TF" | xargs git add
118
118
  else
119
119
  echo "Skipping infra lint (terraform not installed)"
120
120
  fi
@@ -6,30 +6,30 @@ echo "Git hooks configured."
6
6
  <% if (components.includes('fastapi')) { %>
7
7
 
8
8
  cd <%= paths.fastapi %> && uv sync --all-extras && cd ..
9
- echo "FastAPI dependencies installed."
9
+ echo "<%= displayNames.fastapi %> dependencies installed."
10
10
  <% } %>
11
11
  <% if (components.includes('fastify')) { %>
12
12
 
13
13
  cd <%= paths.fastify %> && <%= pm.ci %> && cd ..
14
- echo "Fastify dependencies installed."
14
+ echo "<%= displayNames.fastify %> dependencies installed."
15
15
  <% } %>
16
16
  <% if (components.includes('frontend')) { %>
17
17
 
18
18
  cd <%= paths.frontend %> && <%= pm.ci %> && cd ..
19
- echo "Frontend dependencies installed."
19
+ echo "<%= displayNames.frontend %> dependencies installed."
20
20
  <% } %>
21
21
  <% if (components.includes('e2e')) { %>
22
22
 
23
23
  cd <%= paths.e2e %> && <%= pm.ci %> && cd ..
24
- echo "E2E dependencies installed."
24
+ echo "<%= displayNames.e2e %> dependencies installed."
25
25
  <% } %>
26
26
  <% if (components.includes('mobile')) { %>
27
27
 
28
28
  if command -v flutter &>/dev/null; then
29
29
  cd <%= paths.mobile %> && flutter pub get && cd ..
30
- echo "Flutter dependencies installed."
30
+ echo "<%= displayNames.mobile %> dependencies installed."
31
31
  else
32
- echo "Flutter SDK not installed — skipping mobile."
32
+ echo "<%= displayNames.mobile %> skipped (SDK not installed)."
33
33
  fi
34
34
  <% } %>
35
35