create-prisma-php-app 5.0.0-alpha.7 → 5.1.0-alpha.0
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/.github/copilot-instructions.md +142 -0
- package/dist/AGENTS.md +548 -194
- package/dist/bootstrap.php +227 -34
- package/dist/index.js +2 -2
- package/dist/prisma-php.js +2 -2
- package/dist/public/js/pp-reactive-v2.js +1 -1
- package/dist/settings/auto-swagger-docs.ts +10 -10
- package/dist/settings/bs-config.ts +3 -26
- package/dist/settings/build.ts +2 -32
- package/dist/settings/component-map.ts +476 -0
- package/dist/settings/files-list.ts +2 -2
- package/dist/settings/project-name.ts +3 -6
- package/dist/settings/restart-mcp.ts +2 -2
- package/dist/settings/restart-websocket.ts +2 -2
- package/dist/settings/swagger-config.ts +3 -3
- package/dist/settings/utils.ts +3 -3
- package/dist/src/Lib/Auth/Auth.php +53 -12
- package/dist/src/Lib/Middleware/AuthMiddleware.php +2 -2
- package/dist/src/Lib/Middleware/CorsMiddleware.php +72 -0
- package/package.json +1 -1
- package/dist/README.md +0 -213
- package/dist/settings/bs-config.json +0 -6
- package/dist/settings/class-imports.ts +0 -165
- package/dist/settings/class-log.ts +0 -244
- package/dist/settings/component-import-checker.ts +0 -90
- package/dist/settings/files-list.json +0 -1
- package/dist/settings/prisma-schema-config.json +0 -16
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { Engine } from "php-parser";
|
|
4
|
-
import { getFileMeta } from "./utils";
|
|
5
|
-
|
|
6
|
-
const { __dirname } = getFileMeta();
|
|
7
|
-
|
|
8
|
-
const parser = new Engine({
|
|
9
|
-
parser: {
|
|
10
|
-
php8: true,
|
|
11
|
-
suppressErrors: true,
|
|
12
|
-
},
|
|
13
|
-
ast: {
|
|
14
|
-
withPositions: false,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const PROJECT_ROOT = path.join(__dirname, "..");
|
|
19
|
-
export const SRC_DIR = path.join(PROJECT_ROOT, "src");
|
|
20
|
-
const IMPORTS_FILE = path.join(PROJECT_ROOT, "settings/class-imports.json");
|
|
21
|
-
const CLASS_LOG_FILE = path.join(PROJECT_ROOT, "settings/class-log.json");
|
|
22
|
-
|
|
23
|
-
async function saveImportsData(
|
|
24
|
-
data: Record<
|
|
25
|
-
string,
|
|
26
|
-
Array<{ className: string; filePath: string; importer: string }>
|
|
27
|
-
>
|
|
28
|
-
) {
|
|
29
|
-
await fs.writeFile(IMPORTS_FILE, JSON.stringify(data, null, 2), "utf-8");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function loadClassLogData(): Promise<Record<string, any>> {
|
|
33
|
-
try {
|
|
34
|
-
const content = await fs.readFile(CLASS_LOG_FILE, "utf-8");
|
|
35
|
-
return JSON.parse(content);
|
|
36
|
-
} catch {
|
|
37
|
-
return {};
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export async function getAllPhpFiles(dir: string): Promise<string[]> {
|
|
42
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
43
|
-
const files: string[] = [];
|
|
44
|
-
for (const entry of entries) {
|
|
45
|
-
const fullPath = path.join(dir, entry.name);
|
|
46
|
-
if (entry.isDirectory()) {
|
|
47
|
-
files.push(...(await getAllPhpFiles(fullPath)));
|
|
48
|
-
} else if (entry.isFile() && fullPath.endsWith(".php")) {
|
|
49
|
-
files.push(fullPath);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return files;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function combineNamespaces(
|
|
56
|
-
baseNamespace: string,
|
|
57
|
-
subNamespace: string
|
|
58
|
-
): string {
|
|
59
|
-
return (
|
|
60
|
-
baseNamespace.replace(/\\$/, "") + "\\" + subNamespace.replace(/^\\/, "")
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function analyzeImportsInFile(
|
|
65
|
-
filePath: string
|
|
66
|
-
): Promise<Record<string, string>> {
|
|
67
|
-
const code = await fs.readFile(filePath, "utf-8");
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
const ast = parser.parseCode(code, filePath);
|
|
71
|
-
const imports: Record<string, string> = {};
|
|
72
|
-
|
|
73
|
-
function traverse(node: any, baseNamespace = "") {
|
|
74
|
-
if (!node || typeof node !== "object") return;
|
|
75
|
-
|
|
76
|
-
if (Array.isArray(node)) {
|
|
77
|
-
node.forEach((childNode) => traverse(childNode, baseNamespace));
|
|
78
|
-
} else {
|
|
79
|
-
if (node.kind === "usegroup" && node.name) {
|
|
80
|
-
baseNamespace = node.name.name || node.name;
|
|
81
|
-
for (const useItem of node.items || []) {
|
|
82
|
-
if (useItem.kind === "useitem" && useItem.name) {
|
|
83
|
-
const subNamespace = useItem.name.name || useItem.name;
|
|
84
|
-
const fqn = combineNamespaces(baseNamespace, subNamespace);
|
|
85
|
-
const alias = useItem.alias ? useItem.alias.name : subNamespace;
|
|
86
|
-
if (!imports[alias]) {
|
|
87
|
-
imports[alias] = fqn;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (node.kind === "useitem" && node.name) {
|
|
94
|
-
const fqn = node.name.name || node.name;
|
|
95
|
-
const alias = node.alias
|
|
96
|
-
? node.alias.name
|
|
97
|
-
: path.basename(fqn.replace(/\\/g, "/"));
|
|
98
|
-
if (!imports[alias]) {
|
|
99
|
-
imports[alias] = fqn;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
for (const key in node) {
|
|
104
|
-
traverse(node[key], baseNamespace);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
traverse(ast);
|
|
110
|
-
return imports;
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.error(`Error parsing file: ${filePath}`, error);
|
|
113
|
-
return {};
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export async function updateComponentImports() {
|
|
118
|
-
const phpFiles = await getAllPhpFiles(SRC_DIR);
|
|
119
|
-
const allImports: Record<
|
|
120
|
-
string,
|
|
121
|
-
Array<{ fqn: string; importer: string }>
|
|
122
|
-
> = {};
|
|
123
|
-
|
|
124
|
-
for (const file of phpFiles) {
|
|
125
|
-
const fileImports = await analyzeImportsInFile(file);
|
|
126
|
-
for (const [alias, fqn] of Object.entries(fileImports)) {
|
|
127
|
-
if (allImports[alias]) {
|
|
128
|
-
if (
|
|
129
|
-
!allImports[alias].some(
|
|
130
|
-
(entry) => entry.fqn === fqn && entry.importer === file
|
|
131
|
-
)
|
|
132
|
-
) {
|
|
133
|
-
allImports[alias].push({ fqn, importer: file });
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
allImports[alias] = [{ fqn, importer: file }];
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const classLog = await loadClassLogData();
|
|
142
|
-
const filteredImports: Record<
|
|
143
|
-
string,
|
|
144
|
-
Array<{ className: string; filePath: string; importer: string }>
|
|
145
|
-
> = {};
|
|
146
|
-
|
|
147
|
-
for (const [alias, entries] of Object.entries(allImports)) {
|
|
148
|
-
for (const entry of entries) {
|
|
149
|
-
if (classLog[entry.fqn]) {
|
|
150
|
-
const importEntry = {
|
|
151
|
-
className: entry.fqn,
|
|
152
|
-
filePath: classLog[entry.fqn].filePath,
|
|
153
|
-
importer: entry.importer,
|
|
154
|
-
};
|
|
155
|
-
if (filteredImports[alias]) {
|
|
156
|
-
filteredImports[alias].push(importEntry);
|
|
157
|
-
} else {
|
|
158
|
-
filteredImports[alias] = [importEntry];
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
await saveImportsData(filteredImports);
|
|
165
|
-
}
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { Engine } from "php-parser";
|
|
4
|
-
import { getFileMeta } from "./utils.js";
|
|
5
|
-
|
|
6
|
-
const { __dirname } = getFileMeta();
|
|
7
|
-
|
|
8
|
-
const CONFIG_FILE = path.join(__dirname, "..", "prisma-php.json");
|
|
9
|
-
const LOG_FILE = path.join(__dirname, "class-log.json");
|
|
10
|
-
|
|
11
|
-
const SRC_DIR = path.join(__dirname, "..", "src");
|
|
12
|
-
|
|
13
|
-
const IPHPX_INTERFACE = "IPHPX";
|
|
14
|
-
const PHPX_BASE_CLASS = "PHPX";
|
|
15
|
-
|
|
16
|
-
type LogMap = Record<
|
|
17
|
-
string,
|
|
18
|
-
{
|
|
19
|
-
filePath: string;
|
|
20
|
-
baseDir?: string;
|
|
21
|
-
}
|
|
22
|
-
>;
|
|
23
|
-
|
|
24
|
-
interface PrismaPhpConfig {
|
|
25
|
-
projectRootPath?: string;
|
|
26
|
-
excludeFiles?: string[];
|
|
27
|
-
componentScanDirs?: string[];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const parser = new Engine({
|
|
31
|
-
parser: { php8: true, suppressErrors: true },
|
|
32
|
-
ast: { withPositions: false },
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
async function loadConfig(): Promise<PrismaPhpConfig> {
|
|
36
|
-
try {
|
|
37
|
-
const raw = await fs.readFile(CONFIG_FILE, "utf-8");
|
|
38
|
-
return JSON.parse(raw) as PrismaPhpConfig;
|
|
39
|
-
} catch {
|
|
40
|
-
return {};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function resolveProjectRoot(cfg: PrismaPhpConfig): string {
|
|
45
|
-
if (cfg.projectRootPath && path.isAbsolute(cfg.projectRootPath)) {
|
|
46
|
-
return cfg.projectRootPath;
|
|
47
|
-
}
|
|
48
|
-
return path.join(__dirname, "..");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function resolveScanRoots(cfg: PrismaPhpConfig, projectRoot: string): string[] {
|
|
52
|
-
const dirs =
|
|
53
|
-
Array.isArray(cfg.componentScanDirs) && cfg.componentScanDirs.length
|
|
54
|
-
? cfg.componentScanDirs
|
|
55
|
-
: ["src"];
|
|
56
|
-
|
|
57
|
-
return dirs.map((d) => (path.isAbsolute(d) ? d : path.join(projectRoot, d)));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function relativeFromSrc(absPath: string): string {
|
|
61
|
-
const rel = path.relative(SRC_DIR, absPath);
|
|
62
|
-
return rel.replace(/\\/g, "\\");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function normalizeForWinBackslashes(p: string): string {
|
|
66
|
-
return p.replace(/\\/g, "\\");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function pickRootForFile(scanRoots: string[], absPath: string): string {
|
|
70
|
-
for (const root of scanRoots) {
|
|
71
|
-
const rel = path.relative(root, absPath);
|
|
72
|
-
if (rel && !rel.startsWith("..") && !path.isAbsolute(rel)) {
|
|
73
|
-
return root;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return scanRoots[0] ?? path.dirname(absPath);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function saveLogData(logData: LogMap) {
|
|
80
|
-
await fs.writeFile(LOG_FILE, JSON.stringify(logData, null, 2));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function nameToString(n: any): string {
|
|
84
|
-
if (!n) return "";
|
|
85
|
-
if (typeof n === "string") return n;
|
|
86
|
-
if (typeof n.name === "string") return n.name;
|
|
87
|
-
if (Array.isArray(n.name)) {
|
|
88
|
-
return n.name
|
|
89
|
-
.map((p: any) => (typeof p === "string" ? p : p?.name ?? ""))
|
|
90
|
-
.filter(Boolean)
|
|
91
|
-
.join("\\");
|
|
92
|
-
}
|
|
93
|
-
if (n.kind === "name" && typeof n.name === "string") return n.name;
|
|
94
|
-
return String(n.name ?? "");
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function namespaceNodeToString(nsNode: any): string {
|
|
98
|
-
if (!nsNode) return "";
|
|
99
|
-
const s = nameToString(nsNode);
|
|
100
|
-
return s.replace(/^\s+|\s+$/g, "");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async function analyzePhpFile(filePath: string) {
|
|
104
|
-
const code = await fs.readFile(filePath, "utf-8");
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
const ast = parser.parseCode(code, filePath);
|
|
108
|
-
|
|
109
|
-
type Found = {
|
|
110
|
-
fqcn: string;
|
|
111
|
-
name: string;
|
|
112
|
-
implementsIPHPX: boolean;
|
|
113
|
-
extendsPHPX: boolean;
|
|
114
|
-
};
|
|
115
|
-
const classesFound: Found[] = [];
|
|
116
|
-
|
|
117
|
-
function traverse(node: any, currentNs: string) {
|
|
118
|
-
if (Array.isArray(node)) {
|
|
119
|
-
node.forEach((n) => traverse(n, currentNs));
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
if (!node || typeof node !== "object") return;
|
|
123
|
-
|
|
124
|
-
if (node.kind === "namespace") {
|
|
125
|
-
const nsName = namespaceNodeToString(node.name ?? node);
|
|
126
|
-
const nextNs = nsName || "";
|
|
127
|
-
for (const key in node) {
|
|
128
|
-
if (key === "kind" || key === "name") continue;
|
|
129
|
-
traverse(node[key], nextNs);
|
|
130
|
-
}
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (node.kind === "class" && node.name?.name) {
|
|
135
|
-
const className = node.name.name as string;
|
|
136
|
-
|
|
137
|
-
let implementsIPHPX = false;
|
|
138
|
-
if (Array.isArray(node.implements)) {
|
|
139
|
-
implementsIPHPX = node.implements.some((iface: any) => {
|
|
140
|
-
const nm = nameToString(iface);
|
|
141
|
-
const leaf = nm.split("\\").pop()!;
|
|
142
|
-
return leaf === IPHPX_INTERFACE;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
let extendsPHPX = false;
|
|
147
|
-
if (node.extends) {
|
|
148
|
-
const nm = nameToString(node.extends);
|
|
149
|
-
const leaf = nm.split("\\").pop()!;
|
|
150
|
-
extendsPHPX = leaf === PHPX_BASE_CLASS;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const fqcn = (currentNs ? currentNs + "\\" : "") + className;
|
|
154
|
-
classesFound.push({
|
|
155
|
-
fqcn,
|
|
156
|
-
name: className,
|
|
157
|
-
implementsIPHPX,
|
|
158
|
-
extendsPHPX,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
for (const key in node) {
|
|
163
|
-
if (key === "name" || key === "kind") continue;
|
|
164
|
-
if (node[key]) traverse(node[key], currentNs);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
traverse(ast, "");
|
|
169
|
-
return classesFound;
|
|
170
|
-
} catch (error) {
|
|
171
|
-
console.error(`Error parsing file: ${filePath}`, error);
|
|
172
|
-
return [];
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async function updateClassLogForFile(
|
|
177
|
-
absFilePath: string,
|
|
178
|
-
logData: LogMap,
|
|
179
|
-
scanRoots: string[],
|
|
180
|
-
projectRoot: string
|
|
181
|
-
) {
|
|
182
|
-
const classes = await analyzePhpFile(absFilePath);
|
|
183
|
-
const matchedRoot = pickRootForFile(scanRoots, absFilePath);
|
|
184
|
-
const baseDirRelToProject = path
|
|
185
|
-
.relative(projectRoot, matchedRoot)
|
|
186
|
-
.replace(/\\/g, "/");
|
|
187
|
-
|
|
188
|
-
for (const cls of classes) {
|
|
189
|
-
if (cls.implementsIPHPX || cls.extendsPHPX) {
|
|
190
|
-
const classFullName = cls.fqcn;
|
|
191
|
-
|
|
192
|
-
const legacyRelPath = relativeFromSrc(absFilePath);
|
|
193
|
-
|
|
194
|
-
logData[classFullName] = {
|
|
195
|
-
filePath: normalizeForWinBackslashes(legacyRelPath),
|
|
196
|
-
baseDir: baseDirRelToProject,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
async function getAllPhpFiles(dir: string): Promise<string[]> {
|
|
203
|
-
const files: string[] = [];
|
|
204
|
-
try {
|
|
205
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
206
|
-
for (const entry of entries) {
|
|
207
|
-
const fullPath = path.join(dir, entry.name);
|
|
208
|
-
if (entry.isDirectory()) {
|
|
209
|
-
files.push(...(await getAllPhpFiles(fullPath)));
|
|
210
|
-
} else if (entry.isFile() && fullPath.toLowerCase().endsWith(".php")) {
|
|
211
|
-
files.push(fullPath);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
} catch {}
|
|
215
|
-
return files;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export async function updateAllClassLogs() {
|
|
219
|
-
const cfg = await loadConfig();
|
|
220
|
-
const projectRoot = resolveProjectRoot(cfg);
|
|
221
|
-
const scanRoots = resolveScanRoots(cfg, projectRoot);
|
|
222
|
-
|
|
223
|
-
const excludeAbs = new Set(
|
|
224
|
-
(cfg.excludeFiles ?? []).map((p) =>
|
|
225
|
-
path.isAbsolute(p) ? p : path.join(projectRoot, p)
|
|
226
|
-
)
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
const allPhpFiles: string[] = [];
|
|
230
|
-
for (const root of scanRoots) {
|
|
231
|
-
const files = await getAllPhpFiles(root);
|
|
232
|
-
for (const f of files) {
|
|
233
|
-
if (!excludeAbs.has(f)) allPhpFiles.push(f);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const logData: LogMap = {};
|
|
238
|
-
|
|
239
|
-
for (const file of allPhpFiles) {
|
|
240
|
-
await updateClassLogForFile(file, logData, scanRoots, projectRoot);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
await saveLogData(logData);
|
|
244
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "fs";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
|
|
4
|
-
function removeAllHeredocs(code: string): string {
|
|
5
|
-
const heredocRegex =
|
|
6
|
-
/<<<\s*['"]?([a-zA-Z_][a-zA-Z0-9_]*)['"]?\s*\n[\s\S]*?\n[ \t]*\1;?/g;
|
|
7
|
-
return code.replace(heredocRegex, "");
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function removePhpComments(code: string): string {
|
|
11
|
-
code = code.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
12
|
-
code = code.replace(/\/\/.*$/gm, "");
|
|
13
|
-
return code;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function removePhpStrings(code: string): string {
|
|
17
|
-
code = code.replace(/'(?:[^'\\]|\\.)*'/g, "''");
|
|
18
|
-
code = code.replace(/"(?:[^"\\]|\\.)*"/g, '""');
|
|
19
|
-
return code;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function findComponentsInFile(code: string): string[] {
|
|
23
|
-
let cleanedCode = removePhpComments(removeAllHeredocs(code));
|
|
24
|
-
cleanedCode = removePhpStrings(cleanedCode);
|
|
25
|
-
|
|
26
|
-
const componentRegex = /<([A-Z][A-Za-z0-9]*)\s*(?:\s+[^>]*)?\/?>(?!['"])/g;
|
|
27
|
-
const components = new Set<string>();
|
|
28
|
-
let match;
|
|
29
|
-
|
|
30
|
-
while ((match = componentRegex.exec(cleanedCode)) !== null) {
|
|
31
|
-
components.add(match[1]);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return Array.from(components);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function checkComponentImports(
|
|
38
|
-
filePath: string,
|
|
39
|
-
fileImports: Record<
|
|
40
|
-
string,
|
|
41
|
-
| Array<{ className: string; filePath: string; importer?: string }>
|
|
42
|
-
| { className: string; filePath: string; importer?: string }
|
|
43
|
-
>
|
|
44
|
-
) {
|
|
45
|
-
const code = await fs.readFile(filePath, "utf-8");
|
|
46
|
-
const usedComponents = findComponentsInFile(code);
|
|
47
|
-
|
|
48
|
-
const normalizedFilePath = filePath
|
|
49
|
-
.replace(/\\/g, "/")
|
|
50
|
-
.trim()
|
|
51
|
-
.replace(/\/+$/, "")
|
|
52
|
-
.toLowerCase();
|
|
53
|
-
|
|
54
|
-
usedComponents.forEach((component) => {
|
|
55
|
-
const rawMapping = fileImports[component];
|
|
56
|
-
let mappings: Array<{
|
|
57
|
-
className: string;
|
|
58
|
-
filePath: string;
|
|
59
|
-
importer?: string;
|
|
60
|
-
}> = [];
|
|
61
|
-
if (Array.isArray(rawMapping)) {
|
|
62
|
-
mappings = rawMapping;
|
|
63
|
-
} else if (rawMapping) {
|
|
64
|
-
mappings = [rawMapping];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const found = mappings.some((mapping) => {
|
|
68
|
-
const normalizedImporter = (mapping.importer || "")
|
|
69
|
-
.replace(/\\/g, "/")
|
|
70
|
-
.trim()
|
|
71
|
-
.replace(/\/+$/, "")
|
|
72
|
-
.toLowerCase();
|
|
73
|
-
return (
|
|
74
|
-
normalizedFilePath === normalizedImporter ||
|
|
75
|
-
normalizedFilePath.endsWith(normalizedImporter)
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
if (!found) {
|
|
80
|
-
console.warn(
|
|
81
|
-
chalk.yellow("Warning: ") +
|
|
82
|
-
chalk.white("Component ") +
|
|
83
|
-
chalk.redBright(`<${component}>`) +
|
|
84
|
-
chalk.white(" is used in ") +
|
|
85
|
-
chalk.blue(filePath) +
|
|
86
|
-
chalk.white(" but not imported.")
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"swaggerDocsDir": "src/app/swagger-docs/apis",
|
|
3
|
-
"skipDefaultName": [
|
|
4
|
-
"autoincrement",
|
|
5
|
-
"cuid",
|
|
6
|
-
"uuid",
|
|
7
|
-
"now"
|
|
8
|
-
],
|
|
9
|
-
"skipByPropertyValue": {
|
|
10
|
-
"isUpdatedAt": true
|
|
11
|
-
},
|
|
12
|
-
"skipFields": [],
|
|
13
|
-
"generateSwaggerDocsOnly": true,
|
|
14
|
-
"generateEndpoints": false,
|
|
15
|
-
"generatePhpClasses": false
|
|
16
|
-
}
|