create-projx 1.7.2 → 1.7.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.
@@ -8,8 +8,8 @@ import {
8
8
  matchesSkip,
9
9
  saveBaselineRef,
10
10
  writeTemplateToDir
11
- } from "./chunk-XAYCVTHL.js";
12
- import "./chunk-FQPOK3QZ.js";
11
+ } from "./chunk-RA6FWWUM.js";
12
+ import "./chunk-3NL6OTAP.js";
13
13
  export {
14
14
  BASELINE_REF,
15
15
  applyTemplate,
@@ -223,6 +223,7 @@ async function copyStaticFiles(repoDir, dest) {
223
223
  }
224
224
  const staticScripts = [
225
225
  "ci-local.sh",
226
+ "ci-runner-gc.sh",
226
227
  "check-bundle-size.sh",
227
228
  "setup-docker.sh",
228
229
  "setup-ssl.sh",
@@ -344,6 +345,7 @@ var DEFAULT_ROOT_SKIP_PATTERNS = [
344
345
  ".githooks/pre-commit",
345
346
  ".github/workflows/ci.yml",
346
347
  "scripts/ci-local.sh",
348
+ "scripts/ci-runner-gc.sh",
347
349
  "scripts/check-bundle-size.sh",
348
350
  "scripts/setup.sh",
349
351
  "scripts/setup-docker.sh",
@@ -13,7 +13,7 @@ import {
13
13
  toSnake,
14
14
  upsertComponentMarker,
15
15
  writeProjxConfig
16
- } from "./chunk-FQPOK3QZ.js";
16
+ } from "./chunk-3NL6OTAP.js";
17
17
 
18
18
  // src/baseline.ts
19
19
  import { existsSync, writeFileSync, unlinkSync } from "fs";
@@ -126,7 +126,7 @@ function generateVscodeSettings(vars) {
126
126
  // src/baseline.ts
127
127
  var BASELINE_REF = "refs/projx/baseline";
128
128
  async function migrateComponentMarkers(cwd, components, componentPaths, applyDefaults) {
129
- const { readComponentMarker: readComponentMarker2, writeComponentMarker } = await import("./utils-MC7VKL2U.js");
129
+ const { readComponentMarker: readComponentMarker2, writeComponentMarker } = await import("./utils-W4CWICA7.js");
130
130
  for (const component of components) {
131
131
  const dir = componentPaths[component];
132
132
  const markerDir = join2(cwd, dir);
@@ -658,25 +658,35 @@ async function substituteNamesForInstance(inst, dest, name, nameSnake, overrides
658
658
  const isCanonical = path === type;
659
659
  if (type === "fastapi") {
660
660
  const target = isCanonical ? overrides?.fastapi ?? `${name}-fastapi` : `${name}-${path}`;
661
- await replaceInFile(
662
- join2(dest, `${path}/pyproject.toml`),
663
- "projx-fastapi",
664
- target
665
- );
661
+ for (const file of [
662
+ "pyproject.toml",
663
+ "src/configs/_database.py",
664
+ "tests/test_app.py"
665
+ ]) {
666
+ await replaceInFile(
667
+ join2(dest, `${path}/${file}`),
668
+ "projx-fastapi",
669
+ target
670
+ );
671
+ }
666
672
  } else if (type === "fastify") {
667
673
  const target = isCanonical ? overrides?.fastify ?? `${name}-fastify` : `${name}-${path}`;
668
- await replaceInFile(
669
- join2(dest, `${path}/package.json`),
670
- "projx-fastify",
671
- target
672
- );
674
+ for (const file of ["package.json", ".env.example", ".env.test"]) {
675
+ await replaceInFile(
676
+ join2(dest, `${path}/${file}`),
677
+ "projx-fastify",
678
+ target
679
+ );
680
+ }
673
681
  } else if (type === "express") {
674
682
  const target = isCanonical ? overrides?.express ?? `${name}-express` : `${name}-${path}`;
675
- await replaceInFile(
676
- join2(dest, `${path}/package.json`),
677
- "projx-express",
678
- target
679
- );
683
+ for (const file of ["package.json", ".env.example", ".env.test"]) {
684
+ await replaceInFile(
685
+ join2(dest, `${path}/${file}`),
686
+ "projx-express",
687
+ target
688
+ );
689
+ }
680
690
  } else if (type === "frontend") {
681
691
  const target = isCanonical ? overrides?.frontend ?? `${name}-frontend` : `${name}-${path}`;
682
692
  await replaceInFile(
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  matchesSkip,
10
10
  saveBaselineRef,
11
11
  writeTemplateToDir
12
- } from "./chunk-XAYCVTHL.js";
12
+ } from "./chunk-RA6FWWUM.js";
13
13
  import {
14
14
  COMPONENTS,
15
15
  COMPONENT_MARKER,
@@ -36,7 +36,7 @@ import {
36
36
  toSnake,
37
37
  writeComponentMarker,
38
38
  writeProjxConfig
39
- } from "./chunk-FQPOK3QZ.js";
39
+ } from "./chunk-3NL6OTAP.js";
40
40
 
41
41
  // src/index.ts
42
42
  import { existsSync as existsSync11 } from "fs";
@@ -851,7 +851,7 @@ function hasUncommittedChanges(cwd) {
851
851
  async function findPinnedFilesWithUpdates(cwd, repoDir, components, componentPaths, vars, version, componentSkips, rootSkip) {
852
852
  const { mkdtemp: mkdtemp2, rm: rm2, readFile: readFile8 } = await import("fs/promises");
853
853
  const { tmpdir: tmpdir2 } = await import("os");
854
- const { writeTemplateToDir: writeTemplateToDir2 } = await import("./baseline-ZPPJKHBN.js");
854
+ const { writeTemplateToDir: writeTemplateToDir2 } = await import("./baseline-HNSDAHQ4.js");
855
855
  const config = await readProjxConfig(cwd);
856
856
  const rootPinned = Array.isArray(config.skip) ? config.skip : [];
857
857
  const componentPinned = [];
@@ -35,7 +35,7 @@ import {
35
35
  upsertComponentMarker,
36
36
  writeComponentMarker,
37
37
  writeProjxConfig
38
- } from "./chunk-FQPOK3QZ.js";
38
+ } from "./chunk-3NL6OTAP.js";
39
39
  export {
40
40
  COMPONENTS,
41
41
  COMPONENT_MARKER,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-projx",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
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": {
@@ -11,6 +11,9 @@ permissions:
11
11
  contents: read
12
12
  pull-requests: read
13
13
 
14
+ env:
15
+ WS: run-${{ github.run_id }}-${{ github.run_attempt }}
16
+
14
17
  jobs:
15
18
  changes:
16
19
  name: Detect changes
@@ -39,9 +42,12 @@ jobs:
39
42
  <% } %>
40
43
  steps:
41
44
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
45
+ with:
46
+ path: ${{ env.WS }}
42
47
  - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
43
48
  id: filter
44
49
  with:
50
+ working-directory: ${{ env.WS }}
45
51
  filters: |
46
52
  <% for (const inst of fastapiInstances) { %>
47
53
  <%= inst.path %>:
@@ -79,10 +85,15 @@ jobs:
79
85
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
80
86
  with:
81
87
  fetch-depth: 0
82
- - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2
83
- env:
84
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
85
- - run: python3 scripts/style-check.py frontend/src
88
+ path: ${{ env.WS }}
89
+ - name: Install gitleaks
90
+ run: |
91
+ curl -sSL -o /tmp/gitleaks.tar.gz https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz
92
+ tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks
93
+ sudo mv /tmp/gitleaks /usr/local/bin/gitleaks
94
+ - name: Run gitleaks
95
+ run: gitleaks detect --source ${{ env.WS }} --no-git --no-banner --redact --exit-code 1
96
+ - run: python3 ${{ env.WS }}/scripts/style-check.py ${{ env.WS }}/frontend/src
86
97
  <% for (const inst of fastapiInstances) { %>
87
98
 
88
99
  <%= inst.path %>:
@@ -106,7 +117,7 @@ jobs:
106
117
  --health-retries 5
107
118
  defaults:
108
119
  run:
109
- working-directory: <%= inst.path %>
120
+ working-directory: ${{ env.WS }}/<%= inst.path %>
110
121
  env:
111
122
  SQLALCHEMY_DATABASE_URI: postgresql+asyncpg://postgres:postgres@localhost:5432/ci_test
112
123
  JWT_PROVIDER: shared_secret
@@ -114,6 +125,8 @@ jobs:
114
125
  JWT_ALGORITHMS: HS256
115
126
  steps:
116
127
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
128
+ with:
129
+ path: ${{ env.WS }}
117
130
  - uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
118
131
  - run: uv sync --group dev
119
132
  - run: uv run ruff format --check src tests
@@ -123,7 +136,7 @@ jobs:
123
136
  run: |
124
137
  run_pip_audit() {
125
138
  for attempt in 1 2 3; do
126
- if uv run pip-audit --ignore-vuln CVE-2026-3219 --ignore-vuln PYSEC-2025-183; then
139
+ if bash audit.sh; then
127
140
  return 0
128
141
  fi
129
142
  if [ "$attempt" -eq 3 ]; then
@@ -157,12 +170,14 @@ jobs:
157
170
  --health-retries 5
158
171
  defaults:
159
172
  run:
160
- working-directory: <%= inst.path %>
173
+ working-directory: ${{ env.WS }}/<%= inst.path %>
161
174
  env:
162
175
  DATABASE_URL: postgresql://postgres:postgres@localhost:5432/ci_test
163
176
  JWT_SECRET: ci-test-secret # gitleaks:allow
164
177
  steps:
165
178
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
179
+ with:
180
+ path: ${{ env.WS }}
166
181
  <% if (pm.name === 'pnpm') { %>
167
182
  - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
168
183
  with:
@@ -176,7 +191,7 @@ jobs:
176
191
  with:
177
192
  node-version: 22
178
193
  cache: <%= pm.name %>
179
- cache-dependency-path: <%= inst.path %>/<%= pm.lockfile %>
194
+ cache-dependency-path: ${{ env.WS }}/<%= inst.path %>/<%= pm.lockfile %>
180
195
  <% } %>
181
196
  - run: <%= pm.ci %>
182
197
  <% if (orm === 'drizzle') { %>
@@ -216,11 +231,13 @@ jobs:
216
231
  --health-retries 5
217
232
  defaults:
218
233
  run:
219
- working-directory: <%= inst.path %>
234
+ working-directory: ${{ env.WS }}/<%= inst.path %>
220
235
  env:
221
236
  DATABASE_URL: postgresql://postgres:postgres@localhost:5432/ci_test
222
237
  steps:
223
238
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
239
+ with:
240
+ path: ${{ env.WS }}
224
241
  <% if (pm.name === 'pnpm') { %>
225
242
  - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
226
243
  with:
@@ -234,7 +251,7 @@ jobs:
234
251
  with:
235
252
  node-version: 22
236
253
  cache: <%= pm.name %>
237
- cache-dependency-path: <%= inst.path %>/<%= pm.lockfile %>
254
+ cache-dependency-path: ${{ env.WS }}/<%= inst.path %>/<%= pm.lockfile %>
238
255
  <% } %>
239
256
  - run: <%= pm.ci %>
240
257
  <% if (orm === 'drizzle') { %>
@@ -260,9 +277,11 @@ jobs:
260
277
  runs-on: ubuntu-latest
261
278
  defaults:
262
279
  run:
263
- working-directory: <%= inst.path %>
280
+ working-directory: ${{ env.WS }}/<%= inst.path %>
264
281
  steps:
265
282
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
283
+ with:
284
+ path: ${{ env.WS }}
266
285
  <% if (pm.name === 'pnpm') { %>
267
286
  - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
268
287
  with:
@@ -276,7 +295,7 @@ jobs:
276
295
  with:
277
296
  node-version: 22
278
297
  cache: <%= pm.name %>
279
- cache-dependency-path: <%= inst.path %>/<%= pm.lockfile %>
298
+ cache-dependency-path: ${{ env.WS }}/<%= inst.path %>/<%= pm.lockfile %>
280
299
  <% } %>
281
300
  - run: <%= pm.ci %>
282
301
  - run: <%= pm.exec %> prettier --check .
@@ -295,9 +314,11 @@ jobs:
295
314
  runs-on: ubuntu-latest
296
315
  defaults:
297
316
  run:
298
- working-directory: <%= inst.path %>
317
+ working-directory: ${{ env.WS }}/<%= inst.path %>
299
318
  steps:
300
319
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
320
+ with:
321
+ path: ${{ env.WS }}
301
322
  - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
302
323
  with:
303
324
  channel: stable
@@ -317,9 +338,11 @@ jobs:
317
338
  runs-on: ubuntu-latest
318
339
  defaults:
319
340
  run:
320
- working-directory: <%= inst.path %>
341
+ working-directory: ${{ env.WS }}/<%= inst.path %>
321
342
  steps:
322
343
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
344
+ with:
345
+ path: ${{ env.WS }}
323
346
  <% if (pm.name === 'pnpm') { %>
324
347
  - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
325
348
  with:
@@ -333,7 +356,7 @@ jobs:
333
356
  with:
334
357
  node-version: 22
335
358
  cache: <%= pm.name %>
336
- cache-dependency-path: <%= inst.path %>/<%= pm.lockfile %>
359
+ cache-dependency-path: ${{ env.WS }}/<%= inst.path %>/<%= pm.lockfile %>
337
360
  <% } %>
338
361
  - run: <%= pm.ci %>
339
362
  - run: <%= pm.exec %> prettier --check .
@@ -350,9 +373,11 @@ jobs:
350
373
  runs-on: ubuntu-latest
351
374
  defaults:
352
375
  run:
353
- working-directory: <%= inst.path %>/stack
376
+ working-directory: ${{ env.WS }}/<%= inst.path %>/stack
354
377
  steps:
355
378
  - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
379
+ with:
380
+ path: ${{ env.WS }}
356
381
  - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3
357
382
  with:
358
383
  terraform_version: '1.11'
@@ -39,8 +39,8 @@ if [ -n "$<%= inst.upper %>_PY" ]; then
39
39
  echo "$<%= inst.upper %>_PY" | sed 's|^<%= inst.path %>/||' | xargs uv run ruff format
40
40
  echo "$<%= inst.upper %>_PY" | sed 's|^<%= inst.path %>/||' | xargs uv run ruff check --fix
41
41
  uv run mypy
42
- if grep -rEn 'from src\.[a-z_]+(\.[a-z_]+)?\._[a-z_]+ import' src/; then
43
- echo "ERROR: src/ files cannot import from another module's _-prefixed file. Import from the package."
42
+ if grep -rEn 'from src\.[a-z_]+(\.[a-z_]+)?\._[a-z_]+ import' src/ | grep -v 'pragma:.*allow-private-import'; then
43
+ echo "ERROR: src/ files cannot import from another module's _-prefixed file. Import from the package, or add '# pragma: allow-private-import' on the line if the cycle makes a package import impossible."
44
44
  exit 1
45
45
  fi
46
46
  uv run lint-imports