@soulbatical/tetra-dev-toolkit 1.8.5 → 1.8.7
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/bin/tetra-check-rls.js +11 -10
- package/bin/tetra-setup.js +56 -7
- package/package.json +1 -1
package/bin/tetra-check-rls.js
CHANGED
|
@@ -34,17 +34,18 @@ import chalk from 'chalk'
|
|
|
34
34
|
|
|
35
35
|
// Load tetra-core dynamically (it's a peer/workspace dep)
|
|
36
36
|
async function loadTetraCore() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
37
|
+
// Try multiple paths: direct import, monorepo sibling, backend workspace
|
|
38
|
+
const attempts = [
|
|
39
|
+
() => import('@soulbatical/tetra-core'),
|
|
40
|
+
() => import('../../core/dist/index.js'),
|
|
41
|
+
() => import(join(process.cwd(), 'backend', 'node_modules', '@soulbatical', 'tetra-core', 'dist', 'index.js')),
|
|
42
|
+
() => import(join(process.cwd(), 'node_modules', '@soulbatical', 'tetra-core', 'dist', 'index.js')),
|
|
43
|
+
]
|
|
44
|
+
for (const attempt of attempts) {
|
|
45
|
+
try { return await attempt() } catch { /* next */ }
|
|
47
46
|
}
|
|
47
|
+
console.error(chalk.red('ERROR: @soulbatical/tetra-core not found. Install it first.'))
|
|
48
|
+
process.exit(1)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
function findSupabaseConfig() {
|
package/bin/tetra-setup.js
CHANGED
|
@@ -153,7 +153,7 @@ echo "✅ Pre-commit checks passed"
|
|
|
153
153
|
console.log(' ⏭️ .husky/pre-commit already exists (use --force to overwrite)')
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
// Create or extend pre-push hook with hygiene check
|
|
156
|
+
// Create or extend pre-push hook with hygiene check + RLS security gate
|
|
157
157
|
const prePushPath = join(huskyDir, 'pre-push')
|
|
158
158
|
const hygieneBlock = `
|
|
159
159
|
# Tetra hygiene check — blocks push if repo contains clutter
|
|
@@ -167,23 +167,72 @@ if [ $? -ne 0 ]; then
|
|
|
167
167
|
exit 1
|
|
168
168
|
fi
|
|
169
169
|
echo "✅ Repo hygiene passed"
|
|
170
|
+
`
|
|
171
|
+
|
|
172
|
+
// RLS security gate — auto-detects Doppler project from doppler.yaml
|
|
173
|
+
const rlsBlock = `
|
|
174
|
+
# Tetra RLS Security Gate — blocks push if DB has security violations
|
|
175
|
+
# Auto-detects Doppler project from doppler.yaml
|
|
176
|
+
DOPPLER_PROJECT=""
|
|
177
|
+
for dopfile in doppler.yaml backend/doppler.yaml; do
|
|
178
|
+
if [ -f "$dopfile" ]; then
|
|
179
|
+
DOPPLER_PROJECT=$(grep 'project:' "$dopfile" | head -1 | sed 's/.*project: *//')
|
|
180
|
+
break
|
|
181
|
+
fi
|
|
182
|
+
done
|
|
183
|
+
|
|
184
|
+
if [ -n "$DOPPLER_PROJECT" ]; then
|
|
185
|
+
echo ""
|
|
186
|
+
echo "🔐 Running RLS security gate..."
|
|
187
|
+
doppler run --project "$DOPPLER_PROJECT" --config dev_backend -- npx tetra-check-rls --errors-only 2>/dev/null
|
|
188
|
+
RLS_EXIT=$?
|
|
189
|
+
if [ $RLS_EXIT -ne 0 ]; then
|
|
190
|
+
echo ""
|
|
191
|
+
echo "════════════════════════════════════════════════════════════"
|
|
192
|
+
echo "❌ PUSH BLOCKED — RLS SECURITY VIOLATION"
|
|
193
|
+
echo "════════════════════════════════════════════════════════════"
|
|
194
|
+
echo ""
|
|
195
|
+
echo "Fix all errors before pushing."
|
|
196
|
+
echo "Run for details: doppler run --project $DOPPLER_PROJECT --config dev_backend -- npx tetra-check-rls"
|
|
197
|
+
echo ""
|
|
198
|
+
exit 1
|
|
199
|
+
fi
|
|
200
|
+
echo "✅ RLS security gate passed"
|
|
201
|
+
else
|
|
202
|
+
echo "⚠️ No doppler.yaml found — skipping RLS check (add doppler.yaml to enable)"
|
|
203
|
+
fi
|
|
170
204
|
`
|
|
171
205
|
|
|
172
206
|
if (!existsSync(prePushPath)) {
|
|
173
|
-
// No pre-push hook yet — create one
|
|
174
|
-
const prePushContent = `#!/bin/sh\n${hygieneBlock}\n`
|
|
207
|
+
// No pre-push hook yet — create one with both checks
|
|
208
|
+
const prePushContent = `#!/bin/sh\n${hygieneBlock}\n${rlsBlock}\n`
|
|
175
209
|
writeFileSync(prePushPath, prePushContent)
|
|
176
210
|
execSync(`chmod +x ${prePushPath}`)
|
|
177
|
-
console.log(' ✅ Created .husky/pre-push with hygiene
|
|
211
|
+
console.log(' ✅ Created .husky/pre-push with hygiene + RLS security gate')
|
|
178
212
|
} else {
|
|
179
|
-
// Pre-push hook exists — add
|
|
180
|
-
|
|
213
|
+
// Pre-push hook exists — add missing checks
|
|
214
|
+
let existing = readFileSync(prePushPath, 'utf-8')
|
|
215
|
+
let changed = false
|
|
216
|
+
|
|
181
217
|
if (!existing.includes('tetra-audit hygiene')) {
|
|
182
|
-
|
|
218
|
+
existing = existing.trimEnd() + '\n' + hygieneBlock
|
|
219
|
+
changed = true
|
|
183
220
|
console.log(' ✅ Added hygiene check to existing .husky/pre-push')
|
|
184
221
|
} else {
|
|
185
222
|
console.log(' ⏭️ .husky/pre-push already has hygiene check')
|
|
186
223
|
}
|
|
224
|
+
|
|
225
|
+
if (!existing.includes('tetra-check-rls')) {
|
|
226
|
+
existing = existing.trimEnd() + '\n' + rlsBlock
|
|
227
|
+
changed = true
|
|
228
|
+
console.log(' ✅ Added RLS security gate to existing .husky/pre-push')
|
|
229
|
+
} else {
|
|
230
|
+
console.log(' ⏭️ .husky/pre-push already has RLS security gate')
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (changed) {
|
|
234
|
+
writeFileSync(prePushPath, existing)
|
|
235
|
+
}
|
|
187
236
|
}
|
|
188
237
|
|
|
189
238
|
// Add prepare script to package.json
|