@factiii/stack 0.1.108 → 0.1.109
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/dist/plugins/pipelines/factiii/scanfix/start-sh.d.ts +6 -6
- package/dist/plugins/pipelines/factiii/scanfix/start-sh.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/start-sh.js +134 -171
- package/dist/plugins/pipelines/factiii/scanfix/start-sh.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* start.sh scanfix for Factiii Pipeline plugin
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* -
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
4
|
+
* Merges slot-based env setup into existing start.sh:
|
|
5
|
+
* - If start.sh exists: injects IP detection + slot scan + PORT injection
|
|
6
|
+
* between marker comments at the TOP, preserving all existing logic below
|
|
7
|
+
* - If no start.sh: generates a full quick-start script
|
|
8
|
+
*
|
|
9
|
+
* On re-run, only the section between markers is replaced (idempotent).
|
|
10
10
|
*/
|
|
11
11
|
import type { Fix } from '../../../../types/index.js';
|
|
12
12
|
export declare const startShFixes: Fix[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-sh.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/scanfix/start-sh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"start-sh.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/scanfix/start-sh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAmPrE,eAAO,MAAM,YAAY,EAAE,GAAG,EAmD7B,CAAC"}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* start.sh scanfix for Factiii Pipeline plugin
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
*
|
|
8
|
-
* -
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
5
|
+
* Merges slot-based env setup into existing start.sh:
|
|
6
|
+
* - If start.sh exists: injects IP detection + slot scan + PORT injection
|
|
7
|
+
* between marker comments at the TOP, preserving all existing logic below
|
|
8
|
+
* - If no start.sh: generates a full quick-start script
|
|
9
|
+
*
|
|
10
|
+
* On re-run, only the section between markers is replaced (idempotent).
|
|
11
11
|
*/
|
|
12
12
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
13
|
if (k2 === undefined) k2 = k;
|
|
@@ -48,51 +48,23 @@ const fs = __importStar(require("fs"));
|
|
|
48
48
|
const path = __importStar(require("path"));
|
|
49
49
|
const config_helpers_js_1 = require("../../../../utils/config-helpers.js");
|
|
50
50
|
const version_check_js_1 = require("../../../../utils/version-check.js");
|
|
51
|
+
const MARKER_BEGIN = '# ── @factiii/stack slot setup BEGIN ──';
|
|
52
|
+
const MARKER_END = '# ── @factiii/stack slot setup END ──';
|
|
51
53
|
/**
|
|
52
|
-
*
|
|
53
|
-
|
|
54
|
-
const START_SH_MARKER = '# Generated by @factiii/stack';
|
|
55
|
-
/**
|
|
56
|
-
* Generate the full start.sh content
|
|
54
|
+
* Generate the slot setup section (IP detection + sibling scan + PORT + .env injection)
|
|
55
|
+
* This is the block that gets injected between markers.
|
|
57
56
|
*/
|
|
58
|
-
function
|
|
59
|
-
// Detect which compose file exists
|
|
60
|
-
let composeFile = 'docker-compose.yml';
|
|
61
|
-
if (fs.existsSync(path.join(rootDir, 'compose.yml'))) {
|
|
62
|
-
composeFile = 'compose.yml';
|
|
63
|
-
}
|
|
57
|
+
function generateSlotSection() {
|
|
64
58
|
const version = (0, version_check_js_1.getFactiiiVersion)();
|
|
65
|
-
return '
|
|
59
|
+
return MARKER_BEGIN + '\n' +
|
|
66
60
|
'# Generated by @factiii/stack v' + version + '\n' +
|
|
67
|
-
'#\n' +
|
|
68
|
-
'# Quick-start script for local development\n' +
|
|
69
|
-
'# Sets up .env, installs dependencies, starts Docker\n' +
|
|
70
|
-
'#\n' +
|
|
71
|
-
'# Usage: ./start.sh\n' +
|
|
72
|
-
'#\n' +
|
|
73
61
|
'# PORT slot system: PORT=N where N=1-5\n' +
|
|
74
62
|
'# Client port = 3000 + N (e.g. slot 1 = 3001)\n' +
|
|
75
63
|
'# Server port = 5000 + N (e.g. slot 1 = 5001)\n' +
|
|
76
64
|
'#\n' +
|
|
65
|
+
'# This section is auto-managed. Edit code BELOW the END marker.\n' +
|
|
77
66
|
'\n' +
|
|
78
|
-
'
|
|
79
|
-
'\n' +
|
|
80
|
-
'# ── Colors ─────────────────────────────────────────────────\n' +
|
|
81
|
-
'GREEN="\\033[0;32m"\n' +
|
|
82
|
-
'YELLOW="\\033[1;33m"\n' +
|
|
83
|
-
'CYAN="\\033[0;36m"\n' +
|
|
84
|
-
'RED="\\033[0;31m"\n' +
|
|
85
|
-
'NC="\\033[0m"\n' +
|
|
86
|
-
'\n' +
|
|
87
|
-
'REPO_DIR="$(cd "$(dirname "$0")" && pwd)"\n' +
|
|
88
|
-
'REPO_NAME="$(basename "$REPO_DIR")"\n' +
|
|
89
|
-
'\n' +
|
|
90
|
-
'echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"\n' +
|
|
91
|
-
'echo -e "${CYAN} @factiii/stack - Quick Start${NC}"\n' +
|
|
92
|
-
'echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"\n' +
|
|
93
|
-
'echo ""\n' +
|
|
94
|
-
'\n' +
|
|
95
|
-
'# ── Step 1: Detect system IP ──────────────────────────────\n' +
|
|
67
|
+
'# ── Detect system IP ──────────────────────────────────────\n' +
|
|
96
68
|
'detect_ip() {\n' +
|
|
97
69
|
' local ip=""\n' +
|
|
98
70
|
' case "$(uname -s)" in\n' +
|
|
@@ -106,22 +78,23 @@ function generateStartSh(rootDir) {
|
|
|
106
78
|
' ip=$(ipconfig 2>/dev/null | grep -m1 "IPv4" | awk \'{print $NF}\' || echo "")\n' +
|
|
107
79
|
' ;;\n' +
|
|
108
80
|
' esac\n' +
|
|
109
|
-
' # Fallback\n' +
|
|
110
81
|
' if [ -z "$ip" ]; then\n' +
|
|
111
82
|
' ip="127.0.0.1"\n' +
|
|
112
|
-
' echo -e "${YELLOW} Could not detect network IP, using 127.0.0.1${NC}"\n' +
|
|
113
83
|
' fi\n' +
|
|
114
84
|
' echo "$ip"\n' +
|
|
115
85
|
'}\n' +
|
|
116
86
|
'\n' +
|
|
117
87
|
'SYSTEM_IP=$(detect_ip)\n' +
|
|
118
|
-
'
|
|
88
|
+
'REPO_DIR="$(cd "$(dirname "$0")" && pwd)"\n' +
|
|
89
|
+
'REPO_NAME="$(basename "$REPO_DIR")"\n' +
|
|
90
|
+
'\n' +
|
|
91
|
+
'echo "System IP: $SYSTEM_IP"\n' +
|
|
119
92
|
'\n' +
|
|
120
|
-
'# ──
|
|
93
|
+
'# ── Scan sibling repos for stack.yml ──────────────────────\n' +
|
|
121
94
|
'PARENT_DIR="$(dirname "$REPO_DIR")"\n' +
|
|
122
95
|
'SLOT=0\n' +
|
|
123
|
-
'echo -e "${GREEN}[2/7]${NC} Scanning sibling repos..."\n' +
|
|
124
96
|
'SLOT_NUM=0\n' +
|
|
97
|
+
'echo "Scanning sibling repos..."\n' +
|
|
125
98
|
'for dir in "$PARENT_DIR"/*/; do\n' +
|
|
126
99
|
' [ ! -d "$dir" ] && continue\n' +
|
|
127
100
|
' if [ -f "$dir/stack.yml" ] || [ -f "$dir/factiii.yml" ]; then\n' +
|
|
@@ -129,211 +102,188 @@ function generateStartSh(rootDir) {
|
|
|
129
102
|
' SIBLING_NAME="$(basename "$dir")"\n' +
|
|
130
103
|
' if [ "$SIBLING_NAME" = "$REPO_NAME" ]; then\n' +
|
|
131
104
|
' SLOT=$SLOT_NUM\n' +
|
|
132
|
-
' echo
|
|
105
|
+
' echo " [$SLOT_NUM] $SIBLING_NAME <-- this repo"\n' +
|
|
133
106
|
' else\n' +
|
|
134
|
-
' echo
|
|
107
|
+
' echo " [$SLOT_NUM] $SIBLING_NAME"\n' +
|
|
135
108
|
' fi\n' +
|
|
136
109
|
' fi\n' +
|
|
137
110
|
'done\n' +
|
|
138
111
|
'\n' +
|
|
139
112
|
'if [ "$SLOT_NUM" -eq 0 ]; then\n' +
|
|
140
|
-
' echo
|
|
113
|
+
' echo " No sibling repos found with stack.yml"\n' +
|
|
141
114
|
' SLOT=1\n' +
|
|
142
115
|
'fi\n' +
|
|
143
116
|
'\n' +
|
|
144
|
-
'# ──
|
|
145
|
-
'# Check if .env already has PORT\n' +
|
|
117
|
+
'# ── Determine PORT slot ───────────────────────────────────\n' +
|
|
146
118
|
'if [ -f "$REPO_DIR/.env" ] && grep -q "^PORT=" "$REPO_DIR/.env"; then\n' +
|
|
147
119
|
' EXISTING_PORT=$(grep "^PORT=" "$REPO_DIR/.env" | cut -d= -f2)\n' +
|
|
148
120
|
' if [ "$EXISTING_PORT" -ge 1 ] && [ "$EXISTING_PORT" -le 9 ] 2>/dev/null; then\n' +
|
|
149
121
|
' SLOT=$EXISTING_PORT\n' +
|
|
150
|
-
' echo
|
|
151
|
-
' else\n' +
|
|
152
|
-
' echo -e "${YELLOW} PORT=$EXISTING_PORT is not a valid slot (1-5)${NC}"\n' +
|
|
153
|
-
' SLOT=0\n' +
|
|
122
|
+
' echo "Using existing PORT slot: $SLOT"\n' +
|
|
154
123
|
' fi\n' +
|
|
155
124
|
'fi\n' +
|
|
156
125
|
'\n' +
|
|
157
126
|
'if [ "$SLOT" -eq 0 ]; then\n' +
|
|
158
|
-
' echo
|
|
159
|
-
' echo "
|
|
160
|
-
' read -p "
|
|
127
|
+
' echo "Select PORT slot for $REPO_NAME:"\n' +
|
|
128
|
+
' echo " Slot N -> client:300N, server:500N"\n' +
|
|
129
|
+
' read -p " Enter slot number (1-5): " SLOT\n' +
|
|
161
130
|
' if ! [ "$SLOT" -ge 1 ] || ! [ "$SLOT" -le 5 ] 2>/dev/null; then\n' +
|
|
162
|
-
' echo
|
|
131
|
+
' echo "Invalid slot. Using 1."\n' +
|
|
163
132
|
' SLOT=1\n' +
|
|
164
133
|
' fi\n' +
|
|
165
134
|
'fi\n' +
|
|
166
135
|
'\n' +
|
|
167
136
|
'CLIENT_PORT=$((3000 + SLOT))\n' +
|
|
168
137
|
'SERVER_PORT=$((5000 + SLOT))\n' +
|
|
169
|
-
'echo "
|
|
138
|
+
'echo "Slot $SLOT -> Client: $CLIENT_PORT, Server: $SERVER_PORT"\n' +
|
|
170
139
|
'\n' +
|
|
171
|
-
'# ──
|
|
172
|
-
'echo -e "${GREEN}[4/7]${NC} Setting up .env..."\n' +
|
|
140
|
+
'# ── Setup .env with IP + PORT ─────────────────────────────\n' +
|
|
173
141
|
'if [ ! -f "$REPO_DIR/.env" ]; then\n' +
|
|
174
142
|
' if [ -f "$REPO_DIR/.env.example" ]; then\n' +
|
|
175
143
|
' cp "$REPO_DIR/.env.example" "$REPO_DIR/.env"\n' +
|
|
176
|
-
' echo "
|
|
177
|
-
' else\n' +
|
|
178
|
-
' echo -e "${RED} No .env.example found. Create one first.${NC}"\n' +
|
|
179
|
-
' exit 1\n' +
|
|
144
|
+
' echo "Copied .env.example -> .env"\n' +
|
|
180
145
|
' fi\n' +
|
|
181
146
|
'fi\n' +
|
|
182
147
|
'\n' +
|
|
183
|
-
'
|
|
184
|
-
'
|
|
185
|
-
'
|
|
186
|
-
'
|
|
187
|
-
'
|
|
188
|
-
'
|
|
148
|
+
'if [ -f "$REPO_DIR/.env" ]; then\n' +
|
|
149
|
+
' # Inject PORT slot\n' +
|
|
150
|
+
' if grep -q "^PORT=" "$REPO_DIR/.env"; then\n' +
|
|
151
|
+
' sed -i.bak "s/^PORT=.*/PORT=$SLOT/" "$REPO_DIR/.env" && rm -f "$REPO_DIR/.env.bak"\n' +
|
|
152
|
+
' else\n' +
|
|
153
|
+
' echo "PORT=$SLOT" >> "$REPO_DIR/.env"\n' +
|
|
154
|
+
' fi\n' +
|
|
189
155
|
'\n' +
|
|
190
|
-
'# Replace localhost/127.0.0.1 with system IP
|
|
191
|
-
'if [ "$SYSTEM_IP" != "127.0.0.1" ]; then\n' +
|
|
156
|
+
' # Replace localhost/127.0.0.1 with system IP\n' +
|
|
157
|
+
' if [ "$SYSTEM_IP" != "127.0.0.1" ]; then\n' +
|
|
158
|
+
' sed -i.bak \\\n' +
|
|
159
|
+
' -e "s|http://localhost|http://$SYSTEM_IP|g" \\\n' +
|
|
160
|
+
' -e "s|http://127\\.0\\.0\\.1|http://$SYSTEM_IP|g" \\\n' +
|
|
161
|
+
' -e "s|YOUR_IP|$SYSTEM_IP|g" \\\n' +
|
|
162
|
+
' "$REPO_DIR/.env" && rm -f "$REPO_DIR/.env.bak"\n' +
|
|
163
|
+
' echo "Injected IP: $SYSTEM_IP"\n' +
|
|
164
|
+
' fi\n' +
|
|
165
|
+
'\n' +
|
|
166
|
+
' # Update port references in URL values\n' +
|
|
192
167
|
' sed -i.bak \\\n' +
|
|
193
|
-
' -e "s|
|
|
194
|
-
' -e "s
|
|
195
|
-
' -e "s|YOUR_IP|$SYSTEM_IP|g" \\\n' +
|
|
168
|
+
' -e "s|:500[0-9]|:${SERVER_PORT}|g" \\\n' +
|
|
169
|
+
' -e "s|:300[0-9]|:${CLIENT_PORT}|g" \\\n' +
|
|
196
170
|
' "$REPO_DIR/.env" && rm -f "$REPO_DIR/.env.bak"\n' +
|
|
197
|
-
' echo " Injected IP: $SYSTEM_IP"\n' +
|
|
198
|
-
'fi\n' +
|
|
199
|
-
'\n' +
|
|
200
|
-
'# Replace port placeholders in URL values\n' +
|
|
201
|
-
'# Handles patterns like :5001, :3001 etc. for the slot\n' +
|
|
202
|
-
'sed -i.bak \\\n' +
|
|
203
|
-
' -e "s|:500[0-9]|:${SERVER_PORT}|g" \\\n' +
|
|
204
|
-
' -e "s|:300[0-9]|:${CLIENT_PORT}|g" \\\n' +
|
|
205
|
-
' "$REPO_DIR/.env" && rm -f "$REPO_DIR/.env.bak"\n' +
|
|
206
171
|
'\n' +
|
|
207
|
-
'echo "
|
|
208
|
-
'\n' +
|
|
209
|
-
'# ── Step 5: Validate env (basic checks) ─────────────────────\n' +
|
|
210
|
-
'echo -e "${GREEN}[5/7]${NC} Validating .env..."\n' +
|
|
211
|
-
'ISSUES=0\n' +
|
|
212
|
-
'\n' +
|
|
213
|
-
'# Check for https in dev\n' +
|
|
214
|
-
'if grep -qE "^[A-Z_]+=https://" "$REPO_DIR/.env" 2>/dev/null; then\n' +
|
|
215
|
-
' echo -e " ${YELLOW}Warning: .env has https:// URLs (dev should use http://)${NC}"\n' +
|
|
216
|
-
' ISSUES=$((ISSUES + 1))\n' +
|
|
172
|
+
' echo "PORT=$SLOT (client:$CLIENT_PORT, server:$SERVER_PORT)"\n' +
|
|
217
173
|
'fi\n' +
|
|
218
174
|
'\n' +
|
|
219
|
-
'#
|
|
220
|
-
'
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
175
|
+
'# Export for use by the rest of start.sh\n' +
|
|
176
|
+
'export SYSTEM_IP SLOT CLIENT_PORT SERVER_PORT\n' +
|
|
177
|
+
MARKER_END + '\n';
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Generate a full start.sh for repos that don't have one
|
|
181
|
+
*/
|
|
182
|
+
function generateFullStartSh(rootDir) {
|
|
183
|
+
let composeFile = 'docker-compose.yml';
|
|
184
|
+
if (fs.existsSync(path.join(rootDir, 'compose.yml'))) {
|
|
185
|
+
composeFile = 'compose.yml';
|
|
186
|
+
}
|
|
187
|
+
return '#!/usr/bin/env bash\n' +
|
|
188
|
+
'set -e\n' +
|
|
224
189
|
'\n' +
|
|
225
|
-
|
|
226
|
-
' echo " All checks passed"\n' +
|
|
227
|
-
'fi\n' +
|
|
190
|
+
generateSlotSection() +
|
|
228
191
|
'\n' +
|
|
229
|
-
'# ──
|
|
230
|
-
'echo
|
|
192
|
+
'# ── Install dependencies ────────────────────────────────────\n' +
|
|
193
|
+
'echo "Installing dependencies..."\n' +
|
|
231
194
|
'if command -v pnpm &>/dev/null; then\n' +
|
|
232
195
|
' cd "$REPO_DIR" && pnpm install\n' +
|
|
233
196
|
'elif command -v npm &>/dev/null; then\n' +
|
|
234
197
|
' cd "$REPO_DIR" && npm install\n' +
|
|
235
|
-
'else\n' +
|
|
236
|
-
' echo -e "${YELLOW} No package manager found (pnpm/npm). Skipping install.${NC}"\n' +
|
|
237
198
|
'fi\n' +
|
|
238
199
|
'\n' +
|
|
239
|
-
'# ──
|
|
240
|
-
'echo
|
|
200
|
+
'# ── Start Docker ────────────────────────────────────────────\n' +
|
|
201
|
+
'echo "Starting Docker..."\n' +
|
|
241
202
|
'if command -v docker &>/dev/null; then\n' +
|
|
242
203
|
' cd "$REPO_DIR" && docker compose -f ' + composeFile + ' up -d\n' +
|
|
243
|
-
'else\n' +
|
|
244
|
-
' echo -e "${YELLOW} Docker not found. Skipping container startup.${NC}"\n' +
|
|
245
204
|
'fi\n' +
|
|
246
205
|
'\n' +
|
|
247
206
|
'# ── init.sql detection ──────────────────────────────────────\n' +
|
|
248
207
|
'if [ -f "$REPO_DIR/init.sql" ]; then\n' +
|
|
249
208
|
' echo ""\n' +
|
|
250
|
-
' echo
|
|
251
|
-
' echo -e "${YELLOW} init.sql detected${NC}"\n' +
|
|
252
|
-
' echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"\n' +
|
|
253
|
-
' echo ""\n' +
|
|
254
|
-
' echo " How would you like to set up the database?"\n' +
|
|
209
|
+
' echo "init.sql detected. How to set up the database?"\n' +
|
|
255
210
|
' echo " 1) Inject init.sql into the database container"\n' +
|
|
256
211
|
' echo " 2) Use the seed script (pnpm prisma db seed / pnpm seed)"\n' +
|
|
257
|
-
' echo " 3) Skip
|
|
258
|
-
' echo ""\n' +
|
|
212
|
+
' echo " 3) Skip"\n' +
|
|
259
213
|
' read -p " Choose (1/2/3): " DB_CHOICE\n' +
|
|
260
214
|
'\n' +
|
|
261
215
|
' case "$DB_CHOICE" in\n' +
|
|
262
216
|
' 1)\n' +
|
|
263
|
-
'
|
|
264
|
-
' DB_CONTAINER
|
|
265
|
-
' COMPOSE_FILE_PATH="$REPO_DIR/' + composeFile + '"\n' +
|
|
266
|
-
' if [ -f "$COMPOSE_FILE_PATH" ]; then\n' +
|
|
267
|
-
' # Find service using postgres or mysql image\n' +
|
|
268
|
-
' DB_CONTAINER=$(grep -B5 "image:.*postgres\\|image:.*mysql\\|image:.*mariadb" "$COMPOSE_FILE_PATH" | grep "container_name:" | head -1 | awk \'{print $2}\' || echo "")\n' +
|
|
269
|
-
' if [ -z "$DB_CONTAINER" ]; then\n' +
|
|
270
|
-
' # Try service name as container name\n' +
|
|
271
|
-
' DB_CONTAINER=$(docker compose -f "$COMPOSE_FILE_PATH" ps --format "{{.Name}}" 2>/dev/null | grep -iE "db|postgres|mysql" | head -1 || echo "")\n' +
|
|
272
|
-
' fi\n' +
|
|
273
|
-
' fi\n' +
|
|
274
|
-
'\n' +
|
|
275
|
-
' if [ -z "$DB_CONTAINER" ]; then\n' +
|
|
276
|
-
' read -p " DB container name: " DB_CONTAINER\n' +
|
|
277
|
-
' fi\n' +
|
|
278
|
-
'\n' +
|
|
217
|
+
' DB_CONTAINER=$(docker compose -f "$REPO_DIR/' + composeFile + '" ps --format "{{.Name}}" 2>/dev/null | grep -iE "db|postgres|mysql" | head -1 || echo "")\n' +
|
|
218
|
+
' [ -z "$DB_CONTAINER" ] && read -p " DB container name: " DB_CONTAINER\n' +
|
|
279
219
|
' if [ -n "$DB_CONTAINER" ]; then\n' +
|
|
280
|
-
' echo " Waiting for DB container to be ready..."\n' +
|
|
281
220
|
' sleep 3\n' +
|
|
282
|
-
' # Detect DB type from container\n' +
|
|
283
221
|
' if docker exec "$DB_CONTAINER" psql --version &>/dev/null; then\n' +
|
|
284
222
|
' DB_USER=$(grep "POSTGRES_USER" "$REPO_DIR/.env" 2>/dev/null | cut -d= -f2 || echo "postgres")\n' +
|
|
285
223
|
' DB_NAME=$(grep "POSTGRES_DB" "$REPO_DIR/.env" 2>/dev/null | cut -d= -f2 || echo "postgres")\n' +
|
|
286
224
|
' docker exec -i "$DB_CONTAINER" psql -U "${DB_USER:-postgres}" -d "${DB_NAME:-postgres}" < "$REPO_DIR/init.sql"\n' +
|
|
287
|
-
' echo
|
|
225
|
+
' echo "init.sql injected into PostgreSQL"\n' +
|
|
288
226
|
' elif docker exec "$DB_CONTAINER" mysql --version &>/dev/null; then\n' +
|
|
289
227
|
' DB_NAME=$(grep "MYSQL_DATABASE" "$REPO_DIR/.env" 2>/dev/null | cut -d= -f2 || echo "app")\n' +
|
|
290
228
|
' docker exec -i "$DB_CONTAINER" mysql -u root "${DB_NAME:-app}" < "$REPO_DIR/init.sql"\n' +
|
|
291
|
-
' echo
|
|
292
|
-
' else\n' +
|
|
293
|
-
' echo -e " ${RED}Could not detect DB type in container $DB_CONTAINER${NC}"\n' +
|
|
229
|
+
' echo "init.sql injected into MySQL"\n' +
|
|
294
230
|
' fi\n' +
|
|
295
231
|
' fi\n' +
|
|
296
232
|
' ;;\n' +
|
|
297
233
|
' 2)\n' +
|
|
298
|
-
' echo " Running seed..."\n' +
|
|
299
234
|
' cd "$REPO_DIR"\n' +
|
|
300
235
|
' if [ -f "prisma/schema.prisma" ]; then\n' +
|
|
301
|
-
' pnpm prisma db seed 2>/dev/null || npx prisma db seed 2>/dev/null || echo
|
|
236
|
+
' pnpm prisma db seed 2>/dev/null || npx prisma db seed 2>/dev/null || echo "Seed failed"\n' +
|
|
302
237
|
' elif grep -q "\\"seed\\"" package.json 2>/dev/null; then\n' +
|
|
303
|
-
' pnpm seed 2>/dev/null || npm run seed 2>/dev/null || echo
|
|
304
|
-
' else\n' +
|
|
305
|
-
' echo -e "${YELLOW} No seed script found in package.json${NC}"\n' +
|
|
238
|
+
' pnpm seed 2>/dev/null || npm run seed 2>/dev/null || echo "Seed failed"\n' +
|
|
306
239
|
' fi\n' +
|
|
307
240
|
' ;;\n' +
|
|
308
|
-
' *)
|
|
309
|
-
' echo " Skipping database setup"\n' +
|
|
310
|
-
' ;;\n' +
|
|
241
|
+
' *) echo "Skipping database setup" ;;\n' +
|
|
311
242
|
' esac\n' +
|
|
312
243
|
'fi\n' +
|
|
313
244
|
'\n' +
|
|
314
|
-
'# ── Done ─────────────────────────────────────────────────────\n' +
|
|
315
|
-
'echo ""\n' +
|
|
316
|
-
'echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"\n' +
|
|
317
|
-
'echo -e "${GREEN} Ready!${NC}"\n' +
|
|
318
|
-
'echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"\n' +
|
|
319
245
|
'echo ""\n' +
|
|
320
|
-
'echo
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
246
|
+
'echo "Ready! Client: http://$SYSTEM_IP:$CLIENT_PORT Server: http://$SYSTEM_IP:$SERVER_PORT"\n';
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Inject or update the slot section in an existing start.sh
|
|
250
|
+
*/
|
|
251
|
+
function mergeSlotSection(existingContent) {
|
|
252
|
+
const slotSection = generateSlotSection();
|
|
253
|
+
// If markers already exist, replace the section between them
|
|
254
|
+
if (existingContent.includes(MARKER_BEGIN) && existingContent.includes(MARKER_END)) {
|
|
255
|
+
const beforeMarker = existingContent.substring(0, existingContent.indexOf(MARKER_BEGIN));
|
|
256
|
+
const afterMarker = existingContent.substring(existingContent.indexOf(MARKER_END) + MARKER_END.length);
|
|
257
|
+
// Strip leading newline from afterMarker to avoid double blank lines
|
|
258
|
+
const trimmedAfter = afterMarker.startsWith('\n') ? afterMarker.substring(1) : afterMarker;
|
|
259
|
+
return beforeMarker + slotSection + trimmedAfter;
|
|
260
|
+
}
|
|
261
|
+
// No markers yet — inject after shebang + set -e block
|
|
262
|
+
const lines = existingContent.split('\n');
|
|
263
|
+
let insertIndex = 0;
|
|
264
|
+
// Find the right spot: after shebang, comments, set -e, blank lines
|
|
265
|
+
for (let i = 0; i < lines.length; i++) {
|
|
266
|
+
const trimmed = lines[i].trim();
|
|
267
|
+
if (trimmed.startsWith('#!') || trimmed.startsWith('#') || trimmed === '' || trimmed === 'set -e') {
|
|
268
|
+
insertIndex = i + 1;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const before = lines.slice(0, insertIndex).join('\n');
|
|
275
|
+
const after = lines.slice(insertIndex).join('\n');
|
|
276
|
+
return before + '\n\n' + slotSection + '\n' + after;
|
|
326
277
|
}
|
|
327
278
|
exports.startShFixes = [
|
|
328
279
|
{
|
|
329
280
|
id: 'missing-start-sh',
|
|
330
281
|
stage: 'dev',
|
|
331
282
|
severity: 'warning',
|
|
332
|
-
description: '🚀 start.sh
|
|
283
|
+
description: '🚀 start.sh missing slot setup (IP detection + PORT slot injection)',
|
|
333
284
|
scan: async (_config, rootDir) => {
|
|
334
285
|
if (!(0, config_helpers_js_1.hasEnvironments)(_config))
|
|
335
286
|
return false;
|
|
336
|
-
// Only check if a compose file exists (start.sh wraps docker compose)
|
|
337
287
|
const hasCompose = fs.existsSync(path.join(rootDir, 'docker-compose.yml')) ||
|
|
338
288
|
fs.existsSync(path.join(rootDir, 'compose.yml'));
|
|
339
289
|
if (!hasCompose)
|
|
@@ -341,26 +291,39 @@ exports.startShFixes = [
|
|
|
341
291
|
const startPath = path.join(rootDir, 'start.sh');
|
|
342
292
|
if (!fs.existsSync(startPath))
|
|
343
293
|
return true;
|
|
344
|
-
// Check if
|
|
294
|
+
// Check if slot section exists and is current version
|
|
345
295
|
const content = fs.readFileSync(startPath, 'utf8');
|
|
346
|
-
|
|
296
|
+
if (!content.includes(MARKER_BEGIN))
|
|
297
|
+
return true;
|
|
298
|
+
// Check version
|
|
299
|
+
const version = (0, version_check_js_1.getFactiiiVersion)();
|
|
300
|
+
return !content.includes('Generated by @factiii/stack v' + version);
|
|
347
301
|
},
|
|
348
302
|
fix: async (_config, rootDir) => {
|
|
349
|
-
const content = generateStartSh(rootDir);
|
|
350
303
|
const startPath = path.join(rootDir, 'start.sh');
|
|
351
|
-
fs.
|
|
304
|
+
if (fs.existsSync(startPath)) {
|
|
305
|
+
// Existing start.sh — merge slot section into it
|
|
306
|
+
const existing = fs.readFileSync(startPath, 'utf8');
|
|
307
|
+
const merged = mergeSlotSection(existing);
|
|
308
|
+
fs.writeFileSync(startPath, merged, 'utf8');
|
|
309
|
+
console.log(' Merged slot setup into existing start.sh');
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
// No start.sh — generate full version
|
|
313
|
+
const content = generateFullStartSh(rootDir);
|
|
314
|
+
fs.writeFileSync(startPath, content, 'utf8');
|
|
315
|
+
console.log(' Created start.sh (slot-based quick-start)');
|
|
316
|
+
}
|
|
352
317
|
try {
|
|
353
318
|
fs.chmodSync(startPath, 0o755);
|
|
354
319
|
}
|
|
355
320
|
catch {
|
|
356
321
|
// Windows doesn't support chmod
|
|
357
322
|
}
|
|
358
|
-
console.log(' Created start.sh (slot-based quick-start)');
|
|
359
323
|
return true;
|
|
360
324
|
},
|
|
361
|
-
manualFix: '
|
|
362
|
-
'
|
|
363
|
-
' Or manually create with IP detection + slot PORT system',
|
|
325
|
+
manualFix: 'Run: npx stack fix (will inject slot setup into start.sh)\n' +
|
|
326
|
+
' Or manually add IP detection + PORT slot system to start.sh',
|
|
364
327
|
},
|
|
365
328
|
];
|
|
366
329
|
//# sourceMappingURL=start-sh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-sh.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/scanfix/start-sh.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAE7B,2EAAsE;AACtE,yEAAuE;AAEvE
|
|
1
|
+
{"version":3,"file":"start-sh.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/scanfix/start-sh.ts"],"names":[],"mappings":"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"}
|