File size: 2,877 Bytes
7dc685b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';

// PHP file parsers for controllers, Eloquent models, migrations, middleware,
// and Blade views. Split out of parser.js for size.

const fs = require('fs');
const path = require('path');

function tryRead(p) {
  try { return fs.readFileSync(p, 'utf8'); } catch { return null; }
}

function listPhp(dir) {
  if (!fs.existsSync(dir)) return [];
  return fs.readdirSync(dir)
    .filter(f => f.endsWith('.php'))
    .map(f => path.join(dir, f));
}

// Parse a controller PHP file: class name + public methods.
function parseController(file) {
  const src = tryRead(file) || '';
  const cls = (src.match(/class\s+([A-Za-z0-9_]+)/) || [])[1] || path.basename(file, '.php');
  const methods = [];
  const re = /public\s+function\s+([A-Za-z0-9_]+)\s*\(/g;
  let m;
  while ((m = re.exec(src))) methods.push(m[1]);
  return { file, class: cls, methods };
}

// Parse an Eloquent model: class name + table + fillable.
function parseModel(file) {
  const src = tryRead(file) || '';
  const cls = (src.match(/class\s+([A-Za-z0-9_]+)/) || [])[1] || path.basename(file, '.php');
  const table = (src.match(/protected\s+\\\$table\s*=\s*['"]([^'"]+)['"]/) || [])[1];
  const fillableMatch = src.match(/protected\s+\\\$fillable\s*=\s*\[([^\]]*)\]/);
  let fillable = [];
  if (fillableMatch) {
    fillable = fillableMatch[1].match(/['"]([A-Za-z0-9_]+)['"]/g) || [];
    fillable = fillable.map(s => s.replace(/^['"]|['"]$/g, ''));
  }
  return { file, class: cls, table: table || cls.toLowerCase() + 's', fillable };
}

// Parse a migration: table name from Schema::create('x', ...) + columns.
function parseMigration(file) {
  const src = tryRead(file) || '';
  const m = src.match(/Schema::create\s*\(\s*['"]([A-Za-z0-9_]+)['"]/);
  if (!m) return null;
  const table = m[1];
  const cols = [];
  const colRe = /\\\$table->([a-zA-Z]+)\s*\(\s*['"]([A-Za-z0-9_]+)['"]/g;
  let cm;
  while ((cm = colRe.exec(src))) {
    cols.push({ type: cm[1], name: cm[2] });
  }
  return { file, table, cols };
}

// Parse a middleware class: class name.
function parseMiddleware(file) {
  const src = tryRead(file) || '';
  const cls = (src.match(/class\s+([A-Za-z0-9_]+)/) || [])[1] || path.basename(file, '.php');
  return { file, class: cls };
}

// List Blade views (recursive).
function listBlade(dir, base) {
  base = base || dir;
  const out = [];
  if (!fs.existsSync(dir)) return out;
  for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
    const full = path.join(dir, e.name);
    if (e.isDirectory()) out.push(...listBlade(full, base));
    else if (e.name.endsWith('.blade.php')) {
      const rel = path.relative(base, full).replace(/\.blade\.php$/, '').replace(/\//g, '.');
      out.push({ file: full, name: rel });
    }
  }
  return out;
}

module.exports = {
  tryRead, listPhp, parseController, parseModel, parseMigration,
  parseMiddleware, listBlade,
};