47 lines
2.3 KiB
JavaScript
47 lines
2.3 KiB
JavaScript
import { z } from 'zod';
|
|
import { config } from '../../config.js';
|
|
import { runCommand } from '../../lib/runCommand.js';
|
|
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
|
|
import { requireLaravel } from './requireLaravel.js';
|
|
/**
|
|
* Heuristic: treat an expression as a write if it contains common Eloquent /
|
|
* DB mutation method names. Read-only inspections (find, get, all, count,
|
|
* toArray, …) do not require confirm.
|
|
*/
|
|
const WRITE_PATTERN = /\b(save|create|update|delete|destroy|forceDelete|insert|upsert|truncate|updateOrCreate|firstOrCreate|push|attach|detach|sync|restore|increment|decrement)\s*\(/i;
|
|
export function registerTinkerEvalTool(server) {
|
|
server.registerTool('laravel_tinker_eval', {
|
|
title: 'Laravel Tinker Eval',
|
|
description: 'Evaluate a short PHP expression/snippet via `php artisan tinker --execute` for quick data/model inspection. ' +
|
|
'Read-only by convention. Expressions that appear to mutate data (save/create/update/delete/…) require confirm: true.',
|
|
inputSchema: {
|
|
code: z
|
|
.string()
|
|
.min(1)
|
|
.max(4000)
|
|
.describe('PHP expression to evaluate, e.g. "\\\\App\\\\Models\\\\User::count()" or "config(\'app.name\')".'),
|
|
confirm: z
|
|
.boolean()
|
|
.optional()
|
|
.describe('Required as true when the expression appears to perform a write/mutation.'),
|
|
},
|
|
}, async ({ code, confirm }) => {
|
|
try {
|
|
if (WRITE_PATTERN.test(code) && confirm !== true) {
|
|
return errorResult('This expression looks like it mutates data (save/create/update/delete/…). ' +
|
|
'Re-run with confirm: true if you intentionally want to write.');
|
|
}
|
|
const laravel = requireLaravel();
|
|
// --execute runs the snippet non-interactively and prints the result.
|
|
const result = await runCommand('php', ['artisan', 'tinker', `--execute=${code}`], {
|
|
cwd: laravel.root,
|
|
timeoutMs: config.defaultCommandTimeoutMs,
|
|
});
|
|
return jsonResult({ code, writeDetected: WRITE_PATTERN.test(code), ...result });
|
|
}
|
|
catch (error) {
|
|
return errorResult(toErrorMessage(error));
|
|
}
|
|
});
|
|
}
|
|
//# sourceMappingURL=tinkerEval.js.map
|