@coherent.js/cli 1.0.0-beta.2 → 1.0.0-beta.5
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/README.md +4 -12
- package/dist/index.cjs +2101 -11612
- package/dist/index.js +582 -276
- package/package.json +3 -5
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/index.js
|
|
2
2
|
import { Command as Command6 } from "commander";
|
|
3
|
-
import { readFileSync as
|
|
4
|
-
import { fileURLToPath as
|
|
5
|
-
import { dirname as
|
|
3
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
4
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5
|
+
import { dirname as dirname3, join as join8 } from "path";
|
|
6
6
|
import picocolors6 from "picocolors";
|
|
7
7
|
|
|
8
8
|
// src/commands/create.js
|
|
@@ -15,18 +15,42 @@ import { resolve as resolve2 } from "path";
|
|
|
15
15
|
|
|
16
16
|
// src/generators/project-scaffold.js
|
|
17
17
|
import { writeFileSync, mkdirSync } from "node:fs";
|
|
18
|
-
import { join, dirname } from "node:path";
|
|
18
|
+
import { join as join2, dirname as dirname2 } from "node:path";
|
|
19
19
|
import { execSync } from "node:child_process";
|
|
20
20
|
|
|
21
|
+
// src/utils/version.js
|
|
22
|
+
import { readFileSync } from "fs";
|
|
23
|
+
import { join, dirname } from "path";
|
|
24
|
+
import { fileURLToPath } from "url";
|
|
25
|
+
var cachedVersion = null;
|
|
26
|
+
function getCLIVersion() {
|
|
27
|
+
if (cachedVersion) {
|
|
28
|
+
return cachedVersion;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
32
|
+
const __dirname2 = dirname(__filename2);
|
|
33
|
+
const packagePath = join(__dirname2, "..", "..", "package.json");
|
|
34
|
+
const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
|
|
35
|
+
cachedVersion = packageJson.version;
|
|
36
|
+
return cachedVersion;
|
|
37
|
+
} catch {
|
|
38
|
+
cachedVersion = process.env.COHERENT_CLI_VERSION || "1.0.0-beta.3";
|
|
39
|
+
return cachedVersion;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
21
43
|
// src/generators/runtime-scaffold.js
|
|
44
|
+
var cliVersion = getCLIVersion();
|
|
22
45
|
function generateBuiltInServer(options = {}) {
|
|
23
|
-
const { port = 3e3, hasApi = false, hasDatabase = false } = options;
|
|
46
|
+
const { port = 3e3, hasApi = false, hasDatabase = false, hasAuth = false } = options;
|
|
24
47
|
const imports = [
|
|
25
48
|
`import http from 'http';`,
|
|
26
49
|
`import { render } from '@coherent.js/core';`
|
|
27
50
|
];
|
|
28
51
|
if (hasApi) imports.push(`import { setupRoutes } from './api/routes.js';`);
|
|
29
52
|
if (hasDatabase) imports.push(`import { initDatabase } from './db/index.js';`);
|
|
53
|
+
if (hasAuth) imports.push(`import { setupAuthRoutes } from './api/auth.js';`);
|
|
30
54
|
const server = `
|
|
31
55
|
${imports.join("\n")}
|
|
32
56
|
import { HomePage } from './components/HomePage.js';
|
|
@@ -37,15 +61,21 @@ ${hasDatabase ? `// Initialize database
|
|
|
37
61
|
await initDatabase();
|
|
38
62
|
` : ""}${hasApi ? `// Setup API routes
|
|
39
63
|
const apiRoutes = setupRoutes();
|
|
64
|
+
` : ""}${hasAuth ? `// Setup auth routes
|
|
65
|
+
const authRoutes = setupAuthRoutes();
|
|
40
66
|
` : ""}
|
|
41
67
|
const server = http.createServer(async (req, res) => {
|
|
42
68
|
const url = new URL(req.url, \`http://\${req.headers.host}\`);
|
|
43
69
|
|
|
44
|
-
${hasApi ? ` // Handle API routes
|
|
70
|
+
${hasApi || hasAuth ? ` // Handle API routes
|
|
45
71
|
if (url.pathname.startsWith('/api')) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
const allRoutes = [...${hasApi ? "apiRoutes" : "[]"}, ...${hasAuth ? "authRoutes" : "[]"}];
|
|
73
|
+
for (const route of allRoutes) {
|
|
74
|
+
const match = matchRoute(route.path, url.pathname, req.method, route.method);
|
|
75
|
+
if (match) {
|
|
76
|
+
req.params = match.params;
|
|
77
|
+
return route.handler(req, res);
|
|
78
|
+
}
|
|
49
79
|
}
|
|
50
80
|
}
|
|
51
81
|
|
|
@@ -78,6 +108,42 @@ ${hasApi ? ` // Handle API routes
|
|
|
78
108
|
}
|
|
79
109
|
});
|
|
80
110
|
|
|
111
|
+
// Route matching helper
|
|
112
|
+
function matchRoute(routePattern, urlPath, requestMethod, routeMethod) {
|
|
113
|
+
// Check HTTP method
|
|
114
|
+
if (requestMethod !== routeMethod) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Split paths into segments
|
|
119
|
+
const routeSegments = routePattern.split('/').filter(Boolean);
|
|
120
|
+
const urlSegments = urlPath.split('/').filter(Boolean);
|
|
121
|
+
|
|
122
|
+
// Check if lengths match
|
|
123
|
+
if (routeSegments.length !== urlSegments.length) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const params = {};
|
|
128
|
+
|
|
129
|
+
// Match each segment
|
|
130
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
131
|
+
const routeSegment = routeSegments[i];
|
|
132
|
+
const urlSegment = urlSegments[i];
|
|
133
|
+
|
|
134
|
+
// Check for parameter (e.g., :id)
|
|
135
|
+
if (routeSegment.startsWith(':')) {
|
|
136
|
+
const paramName = routeSegment.substring(1);
|
|
137
|
+
params[paramName] = urlSegment;
|
|
138
|
+
} else if (routeSegment !== urlSegment) {
|
|
139
|
+
// Literal segment doesn't match
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return { params };
|
|
145
|
+
}
|
|
146
|
+
|
|
81
147
|
server.listen(PORT, () => {
|
|
82
148
|
console.log(\`Server running at http://localhost:\${PORT}\`);
|
|
83
149
|
});
|
|
@@ -239,20 +305,20 @@ function getRuntimeDependencies(runtime) {
|
|
|
239
305
|
const deps = {
|
|
240
306
|
"built-in": {},
|
|
241
307
|
express: {
|
|
242
|
-
express: "^4.
|
|
243
|
-
"@coherent.js/express":
|
|
308
|
+
express: "^4.19.2",
|
|
309
|
+
"@coherent.js/express": `^${cliVersion}`
|
|
244
310
|
},
|
|
245
311
|
fastify: {
|
|
246
312
|
fastify: "^4.28.1",
|
|
247
313
|
"@fastify/static": "^7.0.4",
|
|
248
|
-
"@coherent.js/fastify":
|
|
314
|
+
"@coherent.js/fastify": `^${cliVersion}`
|
|
249
315
|
},
|
|
250
316
|
koa: {
|
|
251
317
|
koa: "^2.15.3",
|
|
252
318
|
"@koa/router": "^13.0.1",
|
|
253
319
|
"koa-body": "^6.0.1",
|
|
254
320
|
"koa-static": "^5.0.0",
|
|
255
|
-
"@coherent.js/koa":
|
|
321
|
+
"@coherent.js/koa": `^${cliVersion}`
|
|
256
322
|
}
|
|
257
323
|
};
|
|
258
324
|
return deps[runtime] || {};
|
|
@@ -273,6 +339,7 @@ function generateServerFile(runtime, options = {}) {
|
|
|
273
339
|
}
|
|
274
340
|
|
|
275
341
|
// src/generators/database-scaffold.js
|
|
342
|
+
var cliVersion2 = getCLIVersion();
|
|
276
343
|
function generateDatabaseConfig(dbType) {
|
|
277
344
|
const configs = {
|
|
278
345
|
postgres: `
|
|
@@ -493,7 +560,7 @@ process.on('SIGINT', async () => {
|
|
|
493
560
|
function generateExampleModel(dbType) {
|
|
494
561
|
const models = {
|
|
495
562
|
postgres: `
|
|
496
|
-
import { getDatabase } from '
|
|
563
|
+
import { getDatabase } from '../index.js';
|
|
497
564
|
|
|
498
565
|
export class UserModel {
|
|
499
566
|
static async createTable() {
|
|
@@ -546,7 +613,7 @@ export class UserModel {
|
|
|
546
613
|
}
|
|
547
614
|
`,
|
|
548
615
|
mysql: `
|
|
549
|
-
import { getDatabase } from '
|
|
616
|
+
import { getDatabase } from '../index.js';
|
|
550
617
|
|
|
551
618
|
export class UserModel {
|
|
552
619
|
static async createTable() {
|
|
@@ -599,7 +666,7 @@ export class UserModel {
|
|
|
599
666
|
}
|
|
600
667
|
`,
|
|
601
668
|
sqlite: `
|
|
602
|
-
import { getDatabase } from '
|
|
669
|
+
import { getDatabase } from '../index.js';
|
|
603
670
|
|
|
604
671
|
export class UserModel {
|
|
605
672
|
static createTable() {
|
|
@@ -649,7 +716,7 @@ export class UserModel {
|
|
|
649
716
|
}
|
|
650
717
|
`,
|
|
651
718
|
mongodb: `
|
|
652
|
-
import { getDatabase } from '
|
|
719
|
+
import { getDatabase } from '../index.js';
|
|
653
720
|
|
|
654
721
|
export class UserModel {
|
|
655
722
|
static collectionName = 'users';
|
|
@@ -738,19 +805,19 @@ function getDatabaseDependencies(dbType) {
|
|
|
738
805
|
const deps = {
|
|
739
806
|
postgres: {
|
|
740
807
|
pg: "^8.12.0",
|
|
741
|
-
"@coherent.js/database":
|
|
808
|
+
"@coherent.js/database": `^${cliVersion2}`
|
|
742
809
|
},
|
|
743
810
|
mysql: {
|
|
744
811
|
"mysql2": "^3.11.0",
|
|
745
|
-
"@coherent.js/database":
|
|
812
|
+
"@coherent.js/database": `^${cliVersion2}`
|
|
746
813
|
},
|
|
747
814
|
sqlite: {
|
|
748
815
|
"better-sqlite3": "^11.3.0",
|
|
749
|
-
"@coherent.js/database":
|
|
816
|
+
"@coherent.js/database": `^${cliVersion2}`
|
|
750
817
|
},
|
|
751
818
|
mongodb: {
|
|
752
819
|
mongodb: "^6.9.0",
|
|
753
|
-
"@coherent.js/database":
|
|
820
|
+
"@coherent.js/database": `^${cliVersion2}`
|
|
754
821
|
}
|
|
755
822
|
};
|
|
756
823
|
return deps[dbType] || {};
|
|
@@ -1132,6 +1199,158 @@ router.get('/me', authMiddleware, async (req, res) => {
|
|
|
1132
1199
|
});
|
|
1133
1200
|
|
|
1134
1201
|
export default router;
|
|
1202
|
+
`,
|
|
1203
|
+
"built-in": `
|
|
1204
|
+
// Auth routes for built-in HTTP server
|
|
1205
|
+
import { generateToken, verifyToken } from '../middleware/auth.js';
|
|
1206
|
+
import { UserModel } from '../db/models/User.js';
|
|
1207
|
+
|
|
1208
|
+
// Register handler
|
|
1209
|
+
export async function registerHandler(req, res) {
|
|
1210
|
+
try {
|
|
1211
|
+
// Parse JSON body
|
|
1212
|
+
let body = '';
|
|
1213
|
+
req.on('data', chunk => {
|
|
1214
|
+
body += chunk.toString();
|
|
1215
|
+
});
|
|
1216
|
+
|
|
1217
|
+
req.on('end', async () => {
|
|
1218
|
+
try {
|
|
1219
|
+
const { email, name, password } = JSON.parse(body);
|
|
1220
|
+
|
|
1221
|
+
// Validate input
|
|
1222
|
+
if (!email || !name || !password) {
|
|
1223
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1224
|
+
return res.end(JSON.stringify({ error: 'Missing required fields' }));
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// Check if user exists
|
|
1228
|
+
const existingUser = await UserModel.findByEmail(email);
|
|
1229
|
+
if (existingUser) {
|
|
1230
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1231
|
+
return res.end(JSON.stringify({ error: 'User already exists' }));
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// Create user (you should hash the password!)
|
|
1235
|
+
const user = await UserModel.create({ email, name });
|
|
1236
|
+
|
|
1237
|
+
// Generate token
|
|
1238
|
+
const token = generateToken({ id: user.id, email: user.email });
|
|
1239
|
+
|
|
1240
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1241
|
+
res.end(JSON.stringify({ user: { id: user.id, email: user.email, name: user.name }, token }));
|
|
1242
|
+
} catch (error) {
|
|
1243
|
+
console.error('Register error:', error);
|
|
1244
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1245
|
+
res.end(JSON.stringify({ error: 'Registration failed' }));
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1248
|
+
} catch (error) {
|
|
1249
|
+
console.error('Register error:', error);
|
|
1250
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1251
|
+
res.end(JSON.stringify({ error: 'Registration failed' }));
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// Login handler
|
|
1256
|
+
export async function loginHandler(req, res) {
|
|
1257
|
+
try {
|
|
1258
|
+
// Parse JSON body
|
|
1259
|
+
let body = '';
|
|
1260
|
+
req.on('data', chunk => {
|
|
1261
|
+
body += chunk.toString();
|
|
1262
|
+
});
|
|
1263
|
+
|
|
1264
|
+
req.on('end', async () => {
|
|
1265
|
+
try {
|
|
1266
|
+
const { email, password } = JSON.parse(body);
|
|
1267
|
+
|
|
1268
|
+
// Validate input
|
|
1269
|
+
if (!email || !password) {
|
|
1270
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1271
|
+
return res.end(JSON.stringify({ error: 'Missing required fields' }));
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
// Find user
|
|
1275
|
+
const user = await UserModel.findByEmail(email);
|
|
1276
|
+
if (!user) {
|
|
1277
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1278
|
+
return res.end(JSON.stringify({ error: 'Invalid credentials' }));
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
// Verify password (you should implement proper password checking!)
|
|
1282
|
+
|
|
1283
|
+
// Generate token
|
|
1284
|
+
const token = generateToken({ id: user.id, email: user.email });
|
|
1285
|
+
|
|
1286
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1287
|
+
res.end(JSON.stringify({ user: { id: user.id, email: user.email, name: user.name }, token }));
|
|
1288
|
+
} catch (error) {
|
|
1289
|
+
console.error('Login error:', error);
|
|
1290
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1291
|
+
res.end(JSON.stringify({ error: 'Login failed' }));
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1294
|
+
} catch (error) {
|
|
1295
|
+
console.error('Login error:', error);
|
|
1296
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1297
|
+
res.end(JSON.stringify({ error: 'Login failed' }));
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// Get current user handler
|
|
1302
|
+
export async function meHandler(req, res) {
|
|
1303
|
+
try {
|
|
1304
|
+
// Verify token from Authorization header
|
|
1305
|
+
const authHeader = req.headers.authorization;
|
|
1306
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
1307
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1308
|
+
return res.end(JSON.stringify({ error: 'No token provided' }));
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
const token = authHeader.substring(7);
|
|
1312
|
+
const decoded = verifyToken(token);
|
|
1313
|
+
|
|
1314
|
+
if (!decoded) {
|
|
1315
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
1316
|
+
return res.end(JSON.stringify({ error: 'Invalid or expired token' }));
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
const user = await UserModel.findById(decoded.id);
|
|
1320
|
+
if (!user) {
|
|
1321
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
1322
|
+
return res.end(JSON.stringify({ error: 'User not found' }));
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1326
|
+
res.end(JSON.stringify({ user: { id: user.id, email: user.email, name: user.name } }));
|
|
1327
|
+
} catch (error) {
|
|
1328
|
+
console.error('Get user error:', error);
|
|
1329
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1330
|
+
res.end(JSON.stringify({ error: 'Failed to get user' }));
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
// For built-in HTTP server compatibility
|
|
1335
|
+
export function setupAuthRoutes() {
|
|
1336
|
+
return [
|
|
1337
|
+
{
|
|
1338
|
+
path: '/api/auth/register',
|
|
1339
|
+
method: 'POST',
|
|
1340
|
+
handler: registerHandler
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
path: '/api/auth/login',
|
|
1344
|
+
method: 'POST',
|
|
1345
|
+
handler: loginHandler
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
path: '/api/auth/me',
|
|
1349
|
+
method: 'GET',
|
|
1350
|
+
handler: meHandler
|
|
1351
|
+
}
|
|
1352
|
+
];
|
|
1353
|
+
}
|
|
1135
1354
|
`,
|
|
1136
1355
|
fastify: `
|
|
1137
1356
|
import { generateToken } from '../plugins/auth.js';
|
|
@@ -1448,6 +1667,7 @@ function generateAuthScaffolding(authType, runtime) {
|
|
|
1448
1667
|
}
|
|
1449
1668
|
|
|
1450
1669
|
// src/generators/package-scaffold.js
|
|
1670
|
+
var cliVersion3 = getCLIVersion();
|
|
1451
1671
|
function generateApiScaffolding() {
|
|
1452
1672
|
const routes = `
|
|
1453
1673
|
import { createRouter } from '@coherent.js/api';
|
|
@@ -1479,12 +1699,79 @@ router.post('/users', {
|
|
|
1479
1699
|
}
|
|
1480
1700
|
});
|
|
1481
1701
|
|
|
1702
|
+
// Handler for GET /api/users/:id
|
|
1703
|
+
export async function getUsersByIdHandler(req, res) {
|
|
1704
|
+
try {
|
|
1705
|
+
// Extract ID from URL parameters
|
|
1706
|
+
const { id } = req.params;
|
|
1707
|
+
|
|
1708
|
+
// Call the original handler
|
|
1709
|
+
const result = await router.handle('GET', '/users/:id', { params: { id } }, {});
|
|
1710
|
+
|
|
1711
|
+
// Send JSON response
|
|
1712
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1713
|
+
res.end(JSON.stringify(result));
|
|
1714
|
+
} catch (error) {
|
|
1715
|
+
console.error('API Error:', error);
|
|
1716
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1717
|
+
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// Handler for POST /api/users
|
|
1722
|
+
export async function postUsersHandler(req, res) {
|
|
1723
|
+
try {
|
|
1724
|
+
// Parse JSON body
|
|
1725
|
+
let body = '';
|
|
1726
|
+
req.on('data', chunk => {
|
|
1727
|
+
body += chunk.toString();
|
|
1728
|
+
});
|
|
1729
|
+
|
|
1730
|
+
req.on('end', async () => {
|
|
1731
|
+
try {
|
|
1732
|
+
const parsedBody = JSON.parse(body);
|
|
1733
|
+
|
|
1734
|
+
// Call the original handler
|
|
1735
|
+
const result = await router.handle('POST', '/users', { body: parsedBody }, {});
|
|
1736
|
+
|
|
1737
|
+
// Send JSON response
|
|
1738
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1739
|
+
res.end(JSON.stringify(result));
|
|
1740
|
+
} catch (error) {
|
|
1741
|
+
console.error('API Error:', error);
|
|
1742
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1743
|
+
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
1744
|
+
}
|
|
1745
|
+
});
|
|
1746
|
+
} catch (error) {
|
|
1747
|
+
console.error('API Error:', error);
|
|
1748
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
1749
|
+
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
// For built-in HTTP server compatibility
|
|
1754
|
+
export function setupRoutes() {
|
|
1755
|
+
return [
|
|
1756
|
+
{
|
|
1757
|
+
path: '/api/users/:id',
|
|
1758
|
+
method: 'GET',
|
|
1759
|
+
handler: getUsersByIdHandler
|
|
1760
|
+
},
|
|
1761
|
+
{
|
|
1762
|
+
path: '/api/users',
|
|
1763
|
+
method: 'POST',
|
|
1764
|
+
handler: postUsersHandler
|
|
1765
|
+
}
|
|
1766
|
+
];
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1482
1769
|
export default router;
|
|
1483
1770
|
`;
|
|
1484
1771
|
return {
|
|
1485
1772
|
"src/api/routes.js": routes,
|
|
1486
1773
|
dependencies: {
|
|
1487
|
-
"@coherent.js/api":
|
|
1774
|
+
"@coherent.js/api": `^${cliVersion3}`
|
|
1488
1775
|
}
|
|
1489
1776
|
};
|
|
1490
1777
|
}
|
|
@@ -1573,7 +1860,7 @@ if (typeof window !== 'undefined') {
|
|
|
1573
1860
|
"public/js/hydration.js": hydration,
|
|
1574
1861
|
"src/components/InteractiveCounter.js": interactiveExample,
|
|
1575
1862
|
dependencies: {
|
|
1576
|
-
"@coherent.js/client":
|
|
1863
|
+
"@coherent.js/client": `^${cliVersion3}`
|
|
1577
1864
|
}
|
|
1578
1865
|
};
|
|
1579
1866
|
}
|
|
@@ -1634,7 +1921,7 @@ export const i18n = createI18n({
|
|
|
1634
1921
|
"src/i18n/locales/fr.json": frLocale,
|
|
1635
1922
|
"src/i18n/locales/es.json": esLocale,
|
|
1636
1923
|
dependencies: {
|
|
1637
|
-
"@coherent.js/i18n":
|
|
1924
|
+
"@coherent.js/i18n": `^${cliVersion3}`
|
|
1638
1925
|
}
|
|
1639
1926
|
};
|
|
1640
1927
|
}
|
|
@@ -1692,7 +1979,7 @@ export function ContactForm(props = {}) {
|
|
|
1692
1979
|
return {
|
|
1693
1980
|
"src/components/ContactForm.js": exampleForm,
|
|
1694
1981
|
dependencies: {
|
|
1695
|
-
"@coherent.js/forms":
|
|
1982
|
+
"@coherent.js/forms": `^${cliVersion3}`
|
|
1696
1983
|
}
|
|
1697
1984
|
};
|
|
1698
1985
|
}
|
|
@@ -1720,7 +2007,7 @@ export function initDevtools(app) {
|
|
|
1720
2007
|
return {
|
|
1721
2008
|
"src/utils/devtools.js": config,
|
|
1722
2009
|
dependencies: {
|
|
1723
|
-
"@coherent.js/devtools":
|
|
2010
|
+
"@coherent.js/devtools": `^${cliVersion3}`
|
|
1724
2011
|
}
|
|
1725
2012
|
};
|
|
1726
2013
|
}
|
|
@@ -1769,7 +2056,7 @@ export function getSitemap() {
|
|
|
1769
2056
|
return {
|
|
1770
2057
|
"src/utils/seo.js": metaHelper,
|
|
1771
2058
|
dependencies: {
|
|
1772
|
-
"@coherent.js/seo":
|
|
2059
|
+
"@coherent.js/seo": `^${cliVersion3}`
|
|
1773
2060
|
}
|
|
1774
2061
|
};
|
|
1775
2062
|
}
|
|
@@ -1837,7 +2124,7 @@ describe('HomePage', () => {
|
|
|
1837
2124
|
"tests/helpers/testing.js": testHelper,
|
|
1838
2125
|
"tests/components/HomePage.test.js": exampleTest,
|
|
1839
2126
|
dependencies: {
|
|
1840
|
-
"@coherent.js/testing":
|
|
2127
|
+
"@coherent.js/testing": `^${cliVersion3}`
|
|
1841
2128
|
}
|
|
1842
2129
|
};
|
|
1843
2130
|
}
|
|
@@ -1972,6 +2259,7 @@ function getTypeScriptDependencies() {
|
|
|
1972
2259
|
}
|
|
1973
2260
|
|
|
1974
2261
|
// src/generators/project-scaffold.js
|
|
2262
|
+
var cliVersion4 = getCLIVersion();
|
|
1975
2263
|
async function scaffoldProject(projectPath, options) {
|
|
1976
2264
|
const {
|
|
1977
2265
|
name,
|
|
@@ -2012,16 +2300,16 @@ async function scaffoldProject(projectPath, options) {
|
|
|
2012
2300
|
dirs.push("src/i18n", "src/i18n/locales");
|
|
2013
2301
|
}
|
|
2014
2302
|
dirs.forEach((dir) => {
|
|
2015
|
-
mkdirSync(
|
|
2303
|
+
mkdirSync(join2(projectPath, dir), { recursive: true });
|
|
2016
2304
|
});
|
|
2017
2305
|
const packageJson = generatePackageJson(name, { template, runtime, database, auth, packages, language, packageManager });
|
|
2018
|
-
writeFileSync(
|
|
2306
|
+
writeFileSync(join2(projectPath, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
2019
2307
|
if (isTypeScript) {
|
|
2020
2308
|
const tsConfig = generateTsConfig();
|
|
2021
|
-
writeFileSync(
|
|
2309
|
+
writeFileSync(join2(projectPath, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
|
|
2022
2310
|
} else {
|
|
2023
2311
|
const jsConfig = generateJsConfig();
|
|
2024
|
-
writeFileSync(
|
|
2312
|
+
writeFileSync(join2(projectPath, "jsconfig.json"), JSON.stringify(jsConfig, null, 2));
|
|
2025
2313
|
}
|
|
2026
2314
|
const serverContent = generateServerFile(runtime, {
|
|
2027
2315
|
port: 3e3,
|
|
@@ -2029,30 +2317,30 @@ async function scaffoldProject(projectPath, options) {
|
|
|
2029
2317
|
hasDatabase: !!database,
|
|
2030
2318
|
hasAuth: !!auth
|
|
2031
2319
|
});
|
|
2032
|
-
writeFileSync(
|
|
2320
|
+
writeFileSync(join2(projectPath, `src/index${fileExtension}`), serverContent);
|
|
2033
2321
|
await generateHomePageComponent(projectPath, name, isTypeScript, fileExtension);
|
|
2034
2322
|
if (database) {
|
|
2035
2323
|
const dbScaffolding = generateDatabaseScaffolding(database);
|
|
2036
|
-
writeFileSync(
|
|
2037
|
-
writeFileSync(
|
|
2038
|
-
writeFileSync(
|
|
2324
|
+
writeFileSync(join2(projectPath, "src/db/config.js"), dbScaffolding.config);
|
|
2325
|
+
writeFileSync(join2(projectPath, "src/db/index.js"), dbScaffolding.init);
|
|
2326
|
+
writeFileSync(join2(projectPath, "src/db/models/User.js"), dbScaffolding.model);
|
|
2039
2327
|
const existingEnv = "";
|
|
2040
|
-
writeFileSync(
|
|
2328
|
+
writeFileSync(join2(projectPath, ".env.example"), existingEnv + dbScaffolding.env);
|
|
2041
2329
|
}
|
|
2042
2330
|
if (auth) {
|
|
2043
2331
|
const authScaffolding = generateAuthScaffolding(auth, runtime);
|
|
2044
2332
|
const authDir = runtime === "fastify" ? "plugins" : "middleware";
|
|
2045
|
-
writeFileSync(
|
|
2046
|
-
writeFileSync(
|
|
2047
|
-
const envPath =
|
|
2333
|
+
writeFileSync(join2(projectPath, `src/${authDir}/auth.js`), authScaffolding.middleware);
|
|
2334
|
+
writeFileSync(join2(projectPath, "src/api/auth.js"), authScaffolding.routes);
|
|
2335
|
+
const envPath = join2(projectPath, ".env.example");
|
|
2048
2336
|
const existingEnv = "";
|
|
2049
2337
|
writeFileSync(envPath, existingEnv + authScaffolding.env);
|
|
2050
2338
|
}
|
|
2051
2339
|
if (packages.length > 0) {
|
|
2052
2340
|
const { files } = generatePackageScaffolding(packages);
|
|
2053
2341
|
Object.entries(files).forEach(([filePath, content]) => {
|
|
2054
|
-
const fullPath =
|
|
2055
|
-
mkdirSync(
|
|
2342
|
+
const fullPath = join2(projectPath, filePath);
|
|
2343
|
+
mkdirSync(dirname2(fullPath), { recursive: true });
|
|
2056
2344
|
writeFileSync(fullPath, content);
|
|
2057
2345
|
});
|
|
2058
2346
|
}
|
|
@@ -2107,10 +2395,10 @@ function generatePackageJson(name, options) {
|
|
|
2107
2395
|
test: "node --test tests/*.test.js"
|
|
2108
2396
|
},
|
|
2109
2397
|
dependencies: {
|
|
2110
|
-
"@coherent.js/core":
|
|
2398
|
+
"@coherent.js/core": `^${cliVersion4}`
|
|
2111
2399
|
},
|
|
2112
2400
|
devDependencies: {
|
|
2113
|
-
"@coherent.js/cli":
|
|
2401
|
+
"@coherent.js/cli": `^${cliVersion4}`
|
|
2114
2402
|
}
|
|
2115
2403
|
};
|
|
2116
2404
|
if (isTypeScript) {
|
|
@@ -2222,7 +2510,7 @@ export function HomePage(props = {}) {
|
|
|
2222
2510
|
};
|
|
2223
2511
|
}
|
|
2224
2512
|
`;
|
|
2225
|
-
writeFileSync(
|
|
2513
|
+
writeFileSync(join2(projectPath, `src/components/HomePage${fileExtension}`), homePage);
|
|
2226
2514
|
const buttonComponent = isTypeScript ? `/**
|
|
2227
2515
|
* Button Component
|
|
2228
2516
|
*/
|
|
@@ -2258,7 +2546,7 @@ export function Button(props = {}) {
|
|
|
2258
2546
|
};
|
|
2259
2547
|
}
|
|
2260
2548
|
`;
|
|
2261
|
-
writeFileSync(
|
|
2549
|
+
writeFileSync(join2(projectPath, `src/components/Button${fileExtension}`), buttonComponent);
|
|
2262
2550
|
}
|
|
2263
2551
|
function generateCommonFiles(projectPath, name) {
|
|
2264
2552
|
const readme = `# ${name}
|
|
@@ -2269,16 +2557,16 @@ A Coherent.js application built with pure JavaScript objects.
|
|
|
2269
2557
|
|
|
2270
2558
|
\`\`\`bash
|
|
2271
2559
|
# Install dependencies
|
|
2272
|
-
|
|
2560
|
+
pnpm install
|
|
2273
2561
|
|
|
2274
2562
|
# Start development server
|
|
2275
|
-
|
|
2563
|
+
pnpm run dev
|
|
2276
2564
|
|
|
2277
2565
|
# Build for production
|
|
2278
|
-
|
|
2566
|
+
pnpm run build
|
|
2279
2567
|
|
|
2280
2568
|
# Run tests
|
|
2281
|
-
|
|
2569
|
+
pnpm test
|
|
2282
2570
|
\`\`\`
|
|
2283
2571
|
|
|
2284
2572
|
## Project Structure
|
|
@@ -2297,13 +2585,13 @@ tests/ # Test files
|
|
|
2297
2585
|
## Learn More
|
|
2298
2586
|
|
|
2299
2587
|
- [Coherent.js Documentation](https://github.com/Tomdrouv1/coherent.js)
|
|
2300
|
-
- [API Reference](https://github.com/Tomdrouv1/coherent.js/docs/api-reference.md)
|
|
2588
|
+
- [API Reference](https://github.com/Tomdrouv1/coherent.js/tree/main/docs/api-reference.md)
|
|
2301
2589
|
|
|
2302
2590
|
## License
|
|
2303
2591
|
|
|
2304
2592
|
MIT
|
|
2305
2593
|
`;
|
|
2306
|
-
writeFileSync(
|
|
2594
|
+
writeFileSync(join2(projectPath, "README.md"), readme);
|
|
2307
2595
|
const gitignore = `# Dependencies
|
|
2308
2596
|
node_modules/
|
|
2309
2597
|
npm-debug.log*
|
|
@@ -2360,23 +2648,23 @@ logs
|
|
|
2360
2648
|
# Optional REPL history
|
|
2361
2649
|
.node_repl_history
|
|
2362
2650
|
`;
|
|
2363
|
-
writeFileSync(
|
|
2364
|
-
const testFile = `import {
|
|
2365
|
-
import assert from 'node:assert';
|
|
2651
|
+
writeFileSync(join2(projectPath, ".gitignore"), gitignore);
|
|
2652
|
+
const testFile = `import { describe, it, expect } from 'vitest';
|
|
2366
2653
|
import { render } from '@coherent.js/core';
|
|
2367
2654
|
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2655
|
+
describe('Basic Component Rendering', () => {
|
|
2656
|
+
it('renders basic component', () => {
|
|
2657
|
+
const component = {
|
|
2658
|
+
div: {
|
|
2659
|
+
text: 'Hello, World!'
|
|
2660
|
+
}
|
|
2661
|
+
};
|
|
2374
2662
|
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
});
|
|
2378
|
-
|
|
2379
|
-
writeFileSync(
|
|
2663
|
+
const html = render(component);
|
|
2664
|
+
expect(html).toContain('Hello, World!');
|
|
2665
|
+
});
|
|
2666
|
+
});`;
|
|
2667
|
+
writeFileSync(join2(projectPath, "tests/basic.test.js"), testFile);
|
|
2380
2668
|
}
|
|
2381
2669
|
|
|
2382
2670
|
// src/utils/validation.js
|
|
@@ -2699,29 +2987,29 @@ import picocolors2 from "picocolors";
|
|
|
2699
2987
|
|
|
2700
2988
|
// src/generators/component-generator.js
|
|
2701
2989
|
import { writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
2702
|
-
import { join as
|
|
2990
|
+
import { join as join3 } from "path";
|
|
2703
2991
|
async function generateComponent(name, options = {}) {
|
|
2704
2992
|
const { path: path2 = "src/components", template = "basic", skipTest = false, skipStory = false } = options;
|
|
2705
2993
|
const componentName = toPascalCase(name);
|
|
2706
2994
|
const fileName = componentName;
|
|
2707
|
-
const outputDir =
|
|
2995
|
+
const outputDir = join3(process.cwd(), path2);
|
|
2708
2996
|
if (!existsSync3(outputDir)) {
|
|
2709
2997
|
mkdirSync3(outputDir, { recursive: true });
|
|
2710
2998
|
}
|
|
2711
2999
|
const files = [];
|
|
2712
3000
|
const nextSteps = [];
|
|
2713
|
-
const componentPath =
|
|
3001
|
+
const componentPath = join3(outputDir, `${fileName}.js`);
|
|
2714
3002
|
const componentContent = generateComponentContent(componentName, template);
|
|
2715
3003
|
writeFileSync2(componentPath, componentContent);
|
|
2716
3004
|
files.push(componentPath);
|
|
2717
3005
|
if (!skipTest) {
|
|
2718
|
-
const testPath =
|
|
3006
|
+
const testPath = join3(outputDir, `${fileName}.test.js`);
|
|
2719
3007
|
const testContent = generateTestContent(componentName);
|
|
2720
3008
|
writeFileSync2(testPath, testContent);
|
|
2721
3009
|
files.push(testPath);
|
|
2722
3010
|
}
|
|
2723
3011
|
if (!skipStory) {
|
|
2724
|
-
const storyPath =
|
|
3012
|
+
const storyPath = join3(outputDir, `${fileName}.stories.js`);
|
|
2725
3013
|
const storyContent = generateStoryContent(componentName);
|
|
2726
3014
|
writeFileSync2(storyPath, storyContent);
|
|
2727
3015
|
files.push(storyPath);
|
|
@@ -2750,7 +3038,7 @@ function generateBasicComponent(name) {
|
|
|
2750
3038
|
|
|
2751
3039
|
/**
|
|
2752
3040
|
* ${name} component
|
|
2753
|
-
*
|
|
3041
|
+
*
|
|
2754
3042
|
* @param {Object} props - Component properties
|
|
2755
3043
|
* @param {string} props.className - CSS class name
|
|
2756
3044
|
* @param {Array|Object} props.children - Child elements
|
|
@@ -2777,7 +3065,7 @@ function generateFunctionalComponent(name) {
|
|
|
2777
3065
|
|
|
2778
3066
|
/**
|
|
2779
3067
|
* ${name} - Functional component with business logic
|
|
2780
|
-
*
|
|
3068
|
+
*
|
|
2781
3069
|
* @param {Object} props - Component properties
|
|
2782
3070
|
* @param {Array} props.items - Items to display
|
|
2783
3071
|
* @param {Function} props.onItemClick - Callback for item clicks
|
|
@@ -2795,11 +3083,11 @@ export const ${name} = createComponent(({ items = [], onItemClick, className = '
|
|
|
2795
3083
|
div: {
|
|
2796
3084
|
className: \`${name.toLowerCase()} \${className}\`.trim(),
|
|
2797
3085
|
children: [
|
|
2798
|
-
{
|
|
2799
|
-
h3: {
|
|
3086
|
+
{
|
|
3087
|
+
h3: {
|
|
2800
3088
|
className: '${name.toLowerCase()}__title',
|
|
2801
|
-
text: '${name}'
|
|
2802
|
-
}
|
|
3089
|
+
text: '${name}'
|
|
3090
|
+
}
|
|
2803
3091
|
},
|
|
2804
3092
|
{
|
|
2805
3093
|
ul: {
|
|
@@ -2842,17 +3130,17 @@ function generateInteractiveComponent(name) {
|
|
|
2842
3130
|
|
|
2843
3131
|
/**
|
|
2844
3132
|
* ${name} - Interactive component with state management
|
|
2845
|
-
*
|
|
3133
|
+
*
|
|
2846
3134
|
* @param {Object} props - Component properties
|
|
2847
3135
|
* @param {*} props.initialValue - Initial value
|
|
2848
3136
|
* @param {Function} props.onChange - Change callback
|
|
2849
3137
|
* @param {string} props.className - CSS class name
|
|
2850
3138
|
*/
|
|
2851
|
-
export const ${name} = createComponent(({
|
|
2852
|
-
initialValue = '',
|
|
3139
|
+
export const ${name} = createComponent(({
|
|
3140
|
+
initialValue = '',
|
|
2853
3141
|
onChange,
|
|
2854
3142
|
className = '',
|
|
2855
|
-
...props
|
|
3143
|
+
...props
|
|
2856
3144
|
}) => {
|
|
2857
3145
|
// Component state (handled by Coherent.js hydration)
|
|
2858
3146
|
const state = {
|
|
@@ -2929,7 +3217,7 @@ function generateLayoutComponent(name) {
|
|
|
2929
3217
|
|
|
2930
3218
|
/**
|
|
2931
3219
|
* ${name} - Layout component for page structure
|
|
2932
|
-
*
|
|
3220
|
+
*
|
|
2933
3221
|
* @param {Object} props - Component properties
|
|
2934
3222
|
* @param {string} props.title - Page title
|
|
2935
3223
|
* @param {Array|Object} props.children - Child content
|
|
@@ -2937,7 +3225,7 @@ function generateLayoutComponent(name) {
|
|
|
2937
3225
|
* @param {Object} props.footer - Footer content
|
|
2938
3226
|
* @param {string} props.className - CSS class name
|
|
2939
3227
|
*/
|
|
2940
|
-
export const ${name} = createComponent(({
|
|
3228
|
+
export const ${name} = createComponent(({
|
|
2941
3229
|
title = 'Page Title',
|
|
2942
3230
|
children = [],
|
|
2943
3231
|
header = null,
|
|
@@ -3011,38 +3299,39 @@ export const ${name} = createComponent(({
|
|
|
3011
3299
|
`;
|
|
3012
3300
|
}
|
|
3013
3301
|
function generateTestContent(name) {
|
|
3014
|
-
return `import {
|
|
3015
|
-
import assert from 'node:assert';
|
|
3302
|
+
return `import { describe, it, expect } from 'vitest';
|
|
3016
3303
|
import { render } from '@coherent.js/core';
|
|
3017
3304
|
import { ${name} } from './${name}.js';
|
|
3018
3305
|
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
assert(typeof html === 'string');
|
|
3024
|
-
assert(html.length > 0);
|
|
3025
|
-
assert(html.includes('${name.toLowerCase()}'));
|
|
3026
|
-
});
|
|
3306
|
+
describe('${name}', () => {
|
|
3307
|
+
it('renders correctly', () => {
|
|
3308
|
+
const component = ${name}({});
|
|
3309
|
+
const html = render(component);
|
|
3027
3310
|
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
assert(html.includes('test-class'));
|
|
3033
|
-
});
|
|
3311
|
+
expect(typeof html).toBe('string');
|
|
3312
|
+
expect(html.length).toBeGreaterThan(0);
|
|
3313
|
+
expect(html).toContain('${name.toLowerCase()}');
|
|
3314
|
+
});
|
|
3034
3315
|
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
const html = render(component);
|
|
3042
|
-
|
|
3043
|
-
assert(html.includes('Test child content'));
|
|
3316
|
+
it('accepts className prop', () => {
|
|
3317
|
+
const component = ${name}({ className: 'test-class' });
|
|
3318
|
+
const html = render(component);
|
|
3319
|
+
|
|
3320
|
+
expect(html).toContain('test-class');
|
|
3321
|
+
});
|
|
3044
3322
|
});
|
|
3045
|
-
|
|
3323
|
+
|
|
3324
|
+
it('renders children correctly', () => {
|
|
3325
|
+
const children = [
|
|
3326
|
+
{ p: { text: 'Test child content' } }
|
|
3327
|
+
];
|
|
3328
|
+
|
|
3329
|
+
const component = ${name}({ children });
|
|
3330
|
+
const html = render(component);
|
|
3331
|
+
|
|
3332
|
+
expect(html).toContain('Test child content');
|
|
3333
|
+
});
|
|
3334
|
+
});`;
|
|
3046
3335
|
}
|
|
3047
3336
|
function generateStoryContent(name) {
|
|
3048
3337
|
return `import { ${name} } from './${name}.js';
|
|
@@ -3085,23 +3374,23 @@ function toPascalCase(str) {
|
|
|
3085
3374
|
|
|
3086
3375
|
// src/generators/page-generator.js
|
|
3087
3376
|
import { writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
|
|
3088
|
-
import { join as
|
|
3377
|
+
import { join as join4 } from "path";
|
|
3089
3378
|
async function generatePage(name, options = {}) {
|
|
3090
3379
|
const { path: path2 = "src/pages", template = "basic", skipTest = false } = options;
|
|
3091
3380
|
const pageName = toPascalCase2(name);
|
|
3092
3381
|
const fileName = pageName;
|
|
3093
|
-
const outputDir =
|
|
3382
|
+
const outputDir = join4(process.cwd(), path2);
|
|
3094
3383
|
if (!existsSync4(outputDir)) {
|
|
3095
3384
|
mkdirSync4(outputDir, { recursive: true });
|
|
3096
3385
|
}
|
|
3097
3386
|
const files = [];
|
|
3098
3387
|
const nextSteps = [];
|
|
3099
|
-
const pagePath =
|
|
3388
|
+
const pagePath = join4(outputDir, `${fileName}.js`);
|
|
3100
3389
|
const pageContent = generatePageContent(pageName, template);
|
|
3101
3390
|
writeFileSync3(pagePath, pageContent);
|
|
3102
3391
|
files.push(pagePath);
|
|
3103
3392
|
if (!skipTest) {
|
|
3104
|
-
const testPath =
|
|
3393
|
+
const testPath = join4(outputDir, `${fileName}.test.js`);
|
|
3105
3394
|
const testContent = generateTestContent2(pageName);
|
|
3106
3395
|
writeFileSync3(testPath, testContent);
|
|
3107
3396
|
files.push(testPath);
|
|
@@ -3135,7 +3424,7 @@ function generateBasicPage(name) {
|
|
|
3135
3424
|
/**
|
|
3136
3425
|
* ${name} Page Component
|
|
3137
3426
|
* Route: /${routeName}
|
|
3138
|
-
*
|
|
3427
|
+
*
|
|
3139
3428
|
* @param {Object} props - Page properties
|
|
3140
3429
|
* @param {Object} props.params - Route parameters
|
|
3141
3430
|
* @param {Object} props.query - Query parameters
|
|
@@ -3153,17 +3442,17 @@ export const ${name} = createComponent(({ params = {}, query = {}, request, ...p
|
|
|
3153
3442
|
head: {
|
|
3154
3443
|
children: [
|
|
3155
3444
|
{ title: { text: pageTitle } },
|
|
3156
|
-
{
|
|
3157
|
-
meta: {
|
|
3445
|
+
{
|
|
3446
|
+
meta: {
|
|
3158
3447
|
name: 'description',
|
|
3159
3448
|
content: pageDescription
|
|
3160
|
-
}
|
|
3449
|
+
}
|
|
3161
3450
|
},
|
|
3162
|
-
{
|
|
3163
|
-
meta: {
|
|
3164
|
-
name: 'viewport',
|
|
3165
|
-
content: 'width=device-width, initial-scale=1.0'
|
|
3166
|
-
}
|
|
3451
|
+
{
|
|
3452
|
+
meta: {
|
|
3453
|
+
name: 'viewport',
|
|
3454
|
+
content: 'width=device-width, initial-scale=1.0'
|
|
3455
|
+
}
|
|
3167
3456
|
}
|
|
3168
3457
|
]
|
|
3169
3458
|
}
|
|
@@ -3274,10 +3563,10 @@ ${name}.description = '${name} page description';
|
|
|
3274
3563
|
|
|
3275
3564
|
// Usage in router:
|
|
3276
3565
|
// app.get('/${routeName}', (req, res) => {
|
|
3277
|
-
// const html = render(${name}({
|
|
3278
|
-
// params: req.params,
|
|
3566
|
+
// const html = render(${name}({
|
|
3567
|
+
// params: req.params,
|
|
3279
3568
|
// query: req.query,
|
|
3280
|
-
// request: req
|
|
3569
|
+
// request: req
|
|
3281
3570
|
// }));
|
|
3282
3571
|
// res.send(html);
|
|
3283
3572
|
// });
|
|
@@ -3305,11 +3594,11 @@ export const ${name} = createComponent(({ stats = {}, user = null }) => {
|
|
|
3305
3594
|
head: {
|
|
3306
3595
|
children: [
|
|
3307
3596
|
{ title: { text: '${name} Dashboard' } },
|
|
3308
|
-
{
|
|
3309
|
-
meta: {
|
|
3310
|
-
name: 'viewport',
|
|
3311
|
-
content: 'width=device-width, initial-scale=1.0'
|
|
3312
|
-
}
|
|
3597
|
+
{
|
|
3598
|
+
meta: {
|
|
3599
|
+
name: 'viewport',
|
|
3600
|
+
content: 'width=device-width, initial-scale=1.0'
|
|
3601
|
+
}
|
|
3313
3602
|
}
|
|
3314
3603
|
]
|
|
3315
3604
|
}
|
|
@@ -3460,11 +3749,11 @@ export const ${name} = createComponent(({ initialData = {}, errors = {} }) => {
|
|
|
3460
3749
|
head: {
|
|
3461
3750
|
children: [
|
|
3462
3751
|
{ title: { text: '${name} Form' } },
|
|
3463
|
-
{
|
|
3464
|
-
meta: {
|
|
3465
|
-
name: 'viewport',
|
|
3466
|
-
content: 'width=device-width, initial-scale=1.0'
|
|
3467
|
-
}
|
|
3752
|
+
{
|
|
3753
|
+
meta: {
|
|
3754
|
+
name: 'viewport',
|
|
3755
|
+
content: 'width=device-width, initial-scale=1.0'
|
|
3756
|
+
}
|
|
3468
3757
|
}
|
|
3469
3758
|
]
|
|
3470
3759
|
}
|
|
@@ -3604,42 +3893,42 @@ export const ${name} = createComponent(({ initialData = {}, errors = {} }) => {
|
|
|
3604
3893
|
`;
|
|
3605
3894
|
}
|
|
3606
3895
|
function generateTestContent2(name) {
|
|
3607
|
-
return `import {
|
|
3608
|
-
import assert from 'node:assert';
|
|
3896
|
+
return `import { describe, it, expect } from 'vitest';
|
|
3609
3897
|
import { render } from '@coherent.js/core';
|
|
3610
3898
|
import { ${name} } from './${name}.js';
|
|
3611
3899
|
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
});
|
|
3900
|
+
describe('${name} Page', () => {
|
|
3901
|
+
it('renders correctly', () => {
|
|
3902
|
+
const page = ${name}({});
|
|
3903
|
+
const html = render(page);
|
|
3904
|
+
|
|
3905
|
+
expect(typeof html).toBe('string');
|
|
3906
|
+
expect(html.length).toBeGreaterThan(0);
|
|
3907
|
+
expect(html).toContain('<html>');
|
|
3908
|
+
expect(html).toContain('${name}');
|
|
3909
|
+
});
|
|
3621
3910
|
|
|
3622
|
-
|
|
3911
|
+
it('includes proper head elements', () => {
|
|
3623
3912
|
const page = ${name}({});
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
});
|
|
3913
|
+
const html = render(page);
|
|
3914
|
+
|
|
3915
|
+
expect(html).toContain('<title>');
|
|
3916
|
+
expect(html).toContain('<meta');
|
|
3917
|
+
expect(html).toContain('viewport');
|
|
3918
|
+
});
|
|
3919
|
+
|
|
3920
|
+
it('renders with custom props', () => {
|
|
3921
|
+
const props = {
|
|
3922
|
+
params: { id: '123' },
|
|
3923
|
+
query: { search: 'test' }
|
|
3924
|
+
};
|
|
3630
3925
|
|
|
3631
|
-
test('${name} page renders with custom props', () => {
|
|
3632
|
-
const props = {
|
|
3633
|
-
params: { id: '123' },
|
|
3634
|
-
query: { search: 'test' }
|
|
3635
|
-
};
|
|
3636
|
-
|
|
3637
3926
|
const page = ${name}(props);
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
});
|
|
3642
|
-
|
|
3927
|
+
const html = render(page);
|
|
3928
|
+
|
|
3929
|
+
expect(html).toContain('${name}');
|
|
3930
|
+
});
|
|
3931
|
+
});`;
|
|
3643
3932
|
}
|
|
3644
3933
|
function toPascalCase2(str) {
|
|
3645
3934
|
return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : "").replace(/^(.)/, (_, c) => c.toUpperCase());
|
|
@@ -3647,23 +3936,23 @@ function toPascalCase2(str) {
|
|
|
3647
3936
|
|
|
3648
3937
|
// src/generators/api-generator.js
|
|
3649
3938
|
import { writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
3650
|
-
import { join as
|
|
3939
|
+
import { join as join5 } from "path";
|
|
3651
3940
|
async function generateAPI(name, options = {}) {
|
|
3652
3941
|
const { path: path2 = "src/api", template = "rest", skipTest = false } = options;
|
|
3653
3942
|
const apiName = toKebabCase(name);
|
|
3654
3943
|
const fileName = apiName;
|
|
3655
|
-
const outputDir =
|
|
3944
|
+
const outputDir = join5(process.cwd(), path2);
|
|
3656
3945
|
if (!existsSync5(outputDir)) {
|
|
3657
3946
|
mkdirSync5(outputDir, { recursive: true });
|
|
3658
3947
|
}
|
|
3659
3948
|
const files = [];
|
|
3660
3949
|
const nextSteps = [];
|
|
3661
|
-
const apiPath =
|
|
3950
|
+
const apiPath = join5(outputDir, `${fileName}.js`);
|
|
3662
3951
|
const apiContent = generateAPIContent(apiName, name, template);
|
|
3663
3952
|
writeFileSync4(apiPath, apiContent);
|
|
3664
3953
|
files.push(apiPath);
|
|
3665
3954
|
if (!skipTest) {
|
|
3666
|
-
const testPath =
|
|
3955
|
+
const testPath = join5(outputDir, `${fileName}.test.js`);
|
|
3667
3956
|
const testContent = generateTestContent3(apiName, name);
|
|
3668
3957
|
writeFileSync4(testPath, testContent);
|
|
3669
3958
|
files.push(testPath);
|
|
@@ -3696,7 +3985,7 @@ function generateRESTAPI(apiName, originalName) {
|
|
|
3696
3985
|
/**
|
|
3697
3986
|
* ${className} API Routes
|
|
3698
3987
|
* REST API for ${apiName} resources
|
|
3699
|
-
*
|
|
3988
|
+
*
|
|
3700
3989
|
* Base URL: /api/${apiName}
|
|
3701
3990
|
*/
|
|
3702
3991
|
|
|
@@ -3716,14 +4005,14 @@ const sampleData = [
|
|
|
3716
4005
|
const ${apiName}Schema = {
|
|
3717
4006
|
type: 'object',
|
|
3718
4007
|
properties: {
|
|
3719
|
-
name: {
|
|
3720
|
-
type: 'string',
|
|
4008
|
+
name: {
|
|
4009
|
+
type: 'string',
|
|
3721
4010
|
minLength: 1,
|
|
3722
|
-
maxLength: 100
|
|
4011
|
+
maxLength: 100
|
|
3723
4012
|
},
|
|
3724
|
-
description: {
|
|
4013
|
+
description: {
|
|
3725
4014
|
type: 'string',
|
|
3726
|
-
maxLength: 500
|
|
4015
|
+
maxLength: 500
|
|
3727
4016
|
}
|
|
3728
4017
|
},
|
|
3729
4018
|
required: ['name'],
|
|
@@ -3733,14 +4022,14 @@ const ${apiName}Schema = {
|
|
|
3733
4022
|
const ${apiName}UpdateSchema = {
|
|
3734
4023
|
type: 'object',
|
|
3735
4024
|
properties: {
|
|
3736
|
-
name: {
|
|
3737
|
-
type: 'string',
|
|
4025
|
+
name: {
|
|
4026
|
+
type: 'string',
|
|
3738
4027
|
minLength: 1,
|
|
3739
|
-
maxLength: 100
|
|
4028
|
+
maxLength: 100
|
|
3740
4029
|
},
|
|
3741
|
-
description: {
|
|
4030
|
+
description: {
|
|
3742
4031
|
type: 'string',
|
|
3743
|
-
maxLength: 500
|
|
4032
|
+
maxLength: 500
|
|
3744
4033
|
}
|
|
3745
4034
|
},
|
|
3746
4035
|
additionalProperties: false,
|
|
@@ -3755,21 +4044,21 @@ const ${apiName}UpdateSchema = {
|
|
|
3755
4044
|
*/
|
|
3756
4045
|
${camelCaseApiName}API.get('/', (req, res) => {
|
|
3757
4046
|
const { page = 1, limit = 10, search } = req.query;
|
|
3758
|
-
|
|
4047
|
+
|
|
3759
4048
|
let data = [...sampleData];
|
|
3760
|
-
|
|
4049
|
+
|
|
3761
4050
|
// Apply search filter
|
|
3762
4051
|
if (search) {
|
|
3763
|
-
data = data.filter(item =>
|
|
4052
|
+
data = data.filter(item =>
|
|
3764
4053
|
item.name.toLowerCase().includes(search.toLowerCase())
|
|
3765
4054
|
);
|
|
3766
4055
|
}
|
|
3767
|
-
|
|
4056
|
+
|
|
3768
4057
|
// Apply pagination
|
|
3769
4058
|
const startIndex = (page - 1) * limit;
|
|
3770
4059
|
const endIndex = startIndex + parseInt(limit);
|
|
3771
4060
|
const paginatedData = data.slice(startIndex, endIndex);
|
|
3772
|
-
|
|
4061
|
+
|
|
3773
4062
|
return {
|
|
3774
4063
|
data: paginatedData,
|
|
3775
4064
|
pagination: {
|
|
@@ -3788,14 +4077,14 @@ ${camelCaseApiName}API.get('/', (req, res) => {
|
|
|
3788
4077
|
${camelCaseApiName}API.get('/:id', (req, res) => {
|
|
3789
4078
|
const { id } = req.params;
|
|
3790
4079
|
const item = sampleData.find(item => item.id === id);
|
|
3791
|
-
|
|
4080
|
+
|
|
3792
4081
|
if (!item) {
|
|
3793
4082
|
return res.status(404).json({
|
|
3794
4083
|
_error: '${className} not found',
|
|
3795
4084
|
code: 'NOT_FOUND'
|
|
3796
4085
|
});
|
|
3797
4086
|
}
|
|
3798
|
-
|
|
4087
|
+
|
|
3799
4088
|
return { data: item };
|
|
3800
4089
|
});
|
|
3801
4090
|
|
|
@@ -3803,11 +4092,11 @@ ${camelCaseApiName}API.get('/:id', (req, res) => {
|
|
|
3803
4092
|
* POST /${apiName}
|
|
3804
4093
|
* Create a new ${apiName} item
|
|
3805
4094
|
*/
|
|
3806
|
-
${camelCaseApiName}API.post('/',
|
|
4095
|
+
${camelCaseApiName}API.post('/',
|
|
3807
4096
|
withValidation(${apiName}Schema),
|
|
3808
4097
|
(req, res) => {
|
|
3809
4098
|
const { name, description } = req.body;
|
|
3810
|
-
|
|
4099
|
+
|
|
3811
4100
|
const newItem = {
|
|
3812
4101
|
id: String(Date.now()),
|
|
3813
4102
|
name,
|
|
@@ -3815,9 +4104,9 @@ ${camelCaseApiName}API.post('/',
|
|
|
3815
4104
|
createdAt: new Date().toISOString(),
|
|
3816
4105
|
updatedAt: new Date().toISOString()
|
|
3817
4106
|
};
|
|
3818
|
-
|
|
4107
|
+
|
|
3819
4108
|
sampleData.push(newItem);
|
|
3820
|
-
|
|
4109
|
+
|
|
3821
4110
|
return res.status(201).json({
|
|
3822
4111
|
data: newItem,
|
|
3823
4112
|
message: '${className} created successfully'
|
|
@@ -3834,22 +4123,22 @@ ${camelCaseApiName}API.put('/:id',
|
|
|
3834
4123
|
(req, res) => {
|
|
3835
4124
|
const { id } = req.params;
|
|
3836
4125
|
const itemIndex = sampleData.findIndex(item => item.id === id);
|
|
3837
|
-
|
|
4126
|
+
|
|
3838
4127
|
if (itemIndex === -1) {
|
|
3839
4128
|
return res.status(404).json({
|
|
3840
4129
|
_error: '${className} not found',
|
|
3841
4130
|
code: 'NOT_FOUND'
|
|
3842
4131
|
});
|
|
3843
4132
|
}
|
|
3844
|
-
|
|
4133
|
+
|
|
3845
4134
|
const updatedItem = {
|
|
3846
4135
|
...sampleData[itemIndex],
|
|
3847
4136
|
...req.body,
|
|
3848
4137
|
updatedAt: new Date().toISOString()
|
|
3849
4138
|
};
|
|
3850
|
-
|
|
4139
|
+
|
|
3851
4140
|
sampleData[itemIndex] = updatedItem;
|
|
3852
|
-
|
|
4141
|
+
|
|
3853
4142
|
return {
|
|
3854
4143
|
data: updatedItem,
|
|
3855
4144
|
message: '${className} updated successfully'
|
|
@@ -3864,16 +4153,16 @@ ${camelCaseApiName}API.put('/:id',
|
|
|
3864
4153
|
${camelCaseApiName}API.delete('/:id', (req, res) => {
|
|
3865
4154
|
const { id } = req.params;
|
|
3866
4155
|
const itemIndex = sampleData.findIndex(item => item.id === id);
|
|
3867
|
-
|
|
4156
|
+
|
|
3868
4157
|
if (itemIndex === -1) {
|
|
3869
4158
|
return res.status(404).json({
|
|
3870
4159
|
_error: '${className} not found',
|
|
3871
4160
|
code: 'NOT_FOUND'
|
|
3872
4161
|
});
|
|
3873
4162
|
}
|
|
3874
|
-
|
|
4163
|
+
|
|
3875
4164
|
const deletedItem = sampleData.splice(itemIndex, 1)[0];
|
|
3876
|
-
|
|
4165
|
+
|
|
3877
4166
|
return {
|
|
3878
4167
|
data: deletedItem,
|
|
3879
4168
|
message: '${className} deleted successfully'
|
|
@@ -3894,7 +4183,7 @@ export default ${camelCaseApiName}API;
|
|
|
3894
4183
|
// Usage example:
|
|
3895
4184
|
// import express from 'express';
|
|
3896
4185
|
// import ${camelCaseApiName}API from './api/${apiName}.js';
|
|
3897
|
-
//
|
|
4186
|
+
//
|
|
3898
4187
|
// const app = express();
|
|
3899
4188
|
// app.use(express.json());
|
|
3900
4189
|
// app.use('/api', ${camelCaseApiName}API.toExpress());
|
|
@@ -3915,7 +4204,7 @@ function generateRPCAPI(apiName, originalName) {
|
|
|
3915
4204
|
/**
|
|
3916
4205
|
* ${className} RPC API
|
|
3917
4206
|
* Remote Procedure Call API for ${apiName}
|
|
3918
|
-
*
|
|
4207
|
+
*
|
|
3919
4208
|
* Base URL: /rpc/${apiName}
|
|
3920
4209
|
*/
|
|
3921
4210
|
|
|
@@ -3938,10 +4227,10 @@ sampleData.set('2', { id: '2', name: 'Sample ${className} 2', createdAt: new Dat
|
|
|
3938
4227
|
${camelCaseApiName}RPC.post('/list', (req, res) => {
|
|
3939
4228
|
const { params = {} } = req.body;
|
|
3940
4229
|
const { limit = 10, offset = 0 } = params;
|
|
3941
|
-
|
|
4230
|
+
|
|
3942
4231
|
const items = Array.from(sampleData.values())
|
|
3943
4232
|
.slice(offset, offset + limit);
|
|
3944
|
-
|
|
4233
|
+
|
|
3945
4234
|
return {
|
|
3946
4235
|
jsonrpc: '2.0',
|
|
3947
4236
|
result: {
|
|
@@ -3956,7 +4245,7 @@ ${camelCaseApiName}RPC.post('/list', (req, res) => {
|
|
|
3956
4245
|
* RPC Method: ${apiName}.get
|
|
3957
4246
|
* Get a specific ${apiName} item
|
|
3958
4247
|
*/
|
|
3959
|
-
${camelCaseApiName}RPC.post('/get',
|
|
4248
|
+
${camelCaseApiName}RPC.post('/get',
|
|
3960
4249
|
withValidation({
|
|
3961
4250
|
type: 'object',
|
|
3962
4251
|
properties: {
|
|
@@ -3973,7 +4262,7 @@ ${camelCaseApiName}RPC.post('/get',
|
|
|
3973
4262
|
(req, res) => {
|
|
3974
4263
|
const { params } = req.body;
|
|
3975
4264
|
const item = sampleData.get(params.id);
|
|
3976
|
-
|
|
4265
|
+
|
|
3977
4266
|
if (!item) {
|
|
3978
4267
|
return {
|
|
3979
4268
|
jsonrpc: '2.0',
|
|
@@ -3984,7 +4273,7 @@ ${camelCaseApiName}RPC.post('/get',
|
|
|
3984
4273
|
id: req.body.id
|
|
3985
4274
|
};
|
|
3986
4275
|
}
|
|
3987
|
-
|
|
4276
|
+
|
|
3988
4277
|
return {
|
|
3989
4278
|
jsonrpc: '2.0',
|
|
3990
4279
|
result: item,
|
|
@@ -4015,16 +4304,16 @@ ${camelCaseApiName}RPC.post('/create',
|
|
|
4015
4304
|
(req, res) => {
|
|
4016
4305
|
const { params } = req.body;
|
|
4017
4306
|
const id = String(Date.now());
|
|
4018
|
-
|
|
4307
|
+
|
|
4019
4308
|
const newItem = {
|
|
4020
4309
|
id,
|
|
4021
4310
|
...params,
|
|
4022
4311
|
createdAt: new Date(),
|
|
4023
4312
|
updatedAt: new Date()
|
|
4024
4313
|
};
|
|
4025
|
-
|
|
4314
|
+
|
|
4026
4315
|
sampleData.set(id, newItem);
|
|
4027
|
-
|
|
4316
|
+
|
|
4028
4317
|
return {
|
|
4029
4318
|
jsonrpc: '2.0',
|
|
4030
4319
|
result: newItem,
|
|
@@ -4056,7 +4345,7 @@ ${camelCaseApiName}RPC.post('/update',
|
|
|
4056
4345
|
(req, res) => {
|
|
4057
4346
|
const { params } = req.body;
|
|
4058
4347
|
const existing = sampleData.get(params.id);
|
|
4059
|
-
|
|
4348
|
+
|
|
4060
4349
|
if (!existing) {
|
|
4061
4350
|
return {
|
|
4062
4351
|
jsonrpc: '2.0',
|
|
@@ -4067,15 +4356,15 @@ ${camelCaseApiName}RPC.post('/update',
|
|
|
4067
4356
|
id: req.body.id
|
|
4068
4357
|
};
|
|
4069
4358
|
}
|
|
4070
|
-
|
|
4359
|
+
|
|
4071
4360
|
const updated = {
|
|
4072
4361
|
...existing,
|
|
4073
4362
|
...params,
|
|
4074
4363
|
updatedAt: new Date()
|
|
4075
4364
|
};
|
|
4076
|
-
|
|
4365
|
+
|
|
4077
4366
|
sampleData.set(params.id, updated);
|
|
4078
|
-
|
|
4367
|
+
|
|
4079
4368
|
return {
|
|
4080
4369
|
jsonrpc: '2.0',
|
|
4081
4370
|
result: updated,
|
|
@@ -4105,7 +4394,7 @@ ${camelCaseApiName}RPC.post('/delete',
|
|
|
4105
4394
|
(req, res) => {
|
|
4106
4395
|
const { params } = req.body;
|
|
4107
4396
|
const item = sampleData.get(params.id);
|
|
4108
|
-
|
|
4397
|
+
|
|
4109
4398
|
if (!item) {
|
|
4110
4399
|
return {
|
|
4111
4400
|
jsonrpc: '2.0',
|
|
@@ -4116,9 +4405,9 @@ ${camelCaseApiName}RPC.post('/delete',
|
|
|
4116
4405
|
id: req.body.id
|
|
4117
4406
|
};
|
|
4118
4407
|
}
|
|
4119
|
-
|
|
4408
|
+
|
|
4120
4409
|
sampleData.delete(params.id);
|
|
4121
|
-
|
|
4410
|
+
|
|
4122
4411
|
return {
|
|
4123
4412
|
jsonrpc: '2.0',
|
|
4124
4413
|
result: { success: true, deleted: item },
|
|
@@ -4132,17 +4421,17 @@ export default ${camelCaseApiName}RPC;
|
|
|
4132
4421
|
}
|
|
4133
4422
|
function generateTestContent3(apiName, originalName) {
|
|
4134
4423
|
const className = toPascalCase3(originalName);
|
|
4135
|
-
return `import {
|
|
4136
|
-
import assert from 'node:assert';
|
|
4424
|
+
return `import { describe, it, expect } from 'vitest';
|
|
4137
4425
|
import ${apiName}API from './${apiName}.js';
|
|
4138
4426
|
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4427
|
+
describe('${className} API', () => {
|
|
4428
|
+
it('should be defined', () => {
|
|
4429
|
+
expect(typeof ${apiName}API).toBe('object');
|
|
4430
|
+
expect(typeof ${apiName}API.get).toBe('function');
|
|
4431
|
+
expect(typeof ${apiName}API.post).toBe('function');
|
|
4143
4432
|
});
|
|
4144
4433
|
|
|
4145
|
-
|
|
4434
|
+
it('should handle GET requests', async () => {
|
|
4146
4435
|
const mockReq = {
|
|
4147
4436
|
query: {}
|
|
4148
4437
|
};
|
|
@@ -4150,15 +4439,15 @@ test('${className} API should handle GET requests', async () => {
|
|
|
4150
4439
|
status: (code) => mockRes,
|
|
4151
4440
|
json: (data) => data
|
|
4152
4441
|
};
|
|
4153
|
-
|
|
4442
|
+
|
|
4154
4443
|
// This is a basic test structure
|
|
4155
4444
|
// In a real test, you'd use a testing framework like supertest
|
|
4156
|
-
|
|
4445
|
+
expect(true).toBe(true); // Placeholder
|
|
4157
4446
|
});
|
|
4158
4447
|
|
|
4159
4448
|
// Add more specific tests for your API endpoints
|
|
4160
4449
|
// Example:
|
|
4161
|
-
//
|
|
4450
|
+
// it('POST /${apiName} should create new item', async () => {
|
|
4162
4451
|
// // Test implementation
|
|
4163
4452
|
// });
|
|
4164
4453
|
//
|
|
@@ -4290,19 +4579,19 @@ import { Command as Command3 } from "commander";
|
|
|
4290
4579
|
import ora3 from "ora";
|
|
4291
4580
|
import picocolors3 from "picocolors";
|
|
4292
4581
|
import { execSync as execSync2 } from "child_process";
|
|
4293
|
-
import { existsSync as existsSync6, readFileSync } from "fs";
|
|
4294
|
-
import { join as
|
|
4582
|
+
import { existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
|
|
4583
|
+
import { join as join6 } from "path";
|
|
4295
4584
|
var buildCommand = new Command3("build").description("Build the project for production").option("-w, --watch", "watch for changes").option("--analyze", "analyze bundle size").option("--no-minify", "disable minification").option("--no-optimize", "disable optimizations").action(async (options) => {
|
|
4296
4585
|
console.log(picocolors3.cyan("\u{1F3D7}\uFE0F Building Coherent.js project..."));
|
|
4297
4586
|
console.log();
|
|
4298
|
-
const packageJsonPath =
|
|
4587
|
+
const packageJsonPath = join6(process.cwd(), "package.json");
|
|
4299
4588
|
if (!existsSync6(packageJsonPath)) {
|
|
4300
4589
|
console.error(picocolors3.red("\u274C No package.json found. Are you in a project directory?"));
|
|
4301
4590
|
process.exit(1);
|
|
4302
4591
|
}
|
|
4303
4592
|
let packageJson;
|
|
4304
4593
|
try {
|
|
4305
|
-
packageJson = JSON.parse(
|
|
4594
|
+
packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
4306
4595
|
} catch {
|
|
4307
4596
|
console.error(picocolors3.red("\u274C Failed to read package.json"));
|
|
4308
4597
|
process.exit(1);
|
|
@@ -4397,19 +4686,19 @@ import { Command as Command4 } from "commander";
|
|
|
4397
4686
|
import ora4 from "ora";
|
|
4398
4687
|
import picocolors4 from "picocolors";
|
|
4399
4688
|
import { spawn } from "child_process";
|
|
4400
|
-
import { existsSync as existsSync7, readFileSync as
|
|
4401
|
-
import { join as
|
|
4689
|
+
import { existsSync as existsSync7, readFileSync as readFileSync3 } from "fs";
|
|
4690
|
+
import { join as join7 } from "path";
|
|
4402
4691
|
var devCommand = new Command4("dev").description("Start development server with hot reload").option("-p, --port <port>", "port number", "3000").option("-h, --host <host>", "host address", "localhost").option("--open", "open browser automatically").option("--no-hmr", "disable hot module replacement").action(async (options) => {
|
|
4403
4692
|
console.log(picocolors4.cyan("\u{1F680} Starting Coherent.js development server..."));
|
|
4404
4693
|
console.log();
|
|
4405
|
-
const packageJsonPath =
|
|
4694
|
+
const packageJsonPath = join7(process.cwd(), "package.json");
|
|
4406
4695
|
if (!existsSync7(packageJsonPath)) {
|
|
4407
4696
|
console.error(picocolors4.red("\u274C No package.json found. Are you in a project directory?"));
|
|
4408
4697
|
process.exit(1);
|
|
4409
4698
|
}
|
|
4410
4699
|
let packageJson;
|
|
4411
4700
|
try {
|
|
4412
|
-
packageJson = JSON.parse(
|
|
4701
|
+
packageJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
4413
4702
|
} catch {
|
|
4414
4703
|
console.error(picocolors4.red("\u274C Failed to read package.json"));
|
|
4415
4704
|
process.exit(1);
|
|
@@ -4509,11 +4798,11 @@ import { Command as Command5 } from "commander";
|
|
|
4509
4798
|
import prompts3 from "prompts";
|
|
4510
4799
|
import ora5 from "ora";
|
|
4511
4800
|
import picocolors5 from "picocolors";
|
|
4512
|
-
import { existsSync as existsSync10, readFileSync as
|
|
4801
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
|
|
4513
4802
|
import { resolve as resolve5 } from "path";
|
|
4514
4803
|
|
|
4515
4804
|
// src/analyzers/component-analyzer.js
|
|
4516
|
-
import { readFileSync as
|
|
4805
|
+
import { readFileSync as readFileSync4, existsSync as existsSync8 } from "fs";
|
|
4517
4806
|
import { resolve as resolve3 } from "path";
|
|
4518
4807
|
|
|
4519
4808
|
// ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
@@ -4727,7 +5016,7 @@ function expand_(str, isTop) {
|
|
|
4727
5016
|
return expansions;
|
|
4728
5017
|
}
|
|
4729
5018
|
|
|
4730
|
-
// ../../node_modules/.pnpm/minimatch@10.
|
|
5019
|
+
// ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/assert-valid-pattern.js
|
|
4731
5020
|
var MAX_PATTERN_LENGTH = 1024 * 64;
|
|
4732
5021
|
var assertValidPattern = (pattern) => {
|
|
4733
5022
|
if (typeof pattern !== "string") {
|
|
@@ -4738,7 +5027,7 @@ var assertValidPattern = (pattern) => {
|
|
|
4738
5027
|
}
|
|
4739
5028
|
};
|
|
4740
5029
|
|
|
4741
|
-
// ../../node_modules/.pnpm/minimatch@10.
|
|
5030
|
+
// ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/brace-expressions.js
|
|
4742
5031
|
var posixClasses = {
|
|
4743
5032
|
"[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true],
|
|
4744
5033
|
"[:alpha:]": ["\\p{L}\\p{Nl}", true],
|
|
@@ -4847,12 +5136,15 @@ var parseClass = (glob2, position) => {
|
|
|
4847
5136
|
return [comb, uflag, endPos - pos, true];
|
|
4848
5137
|
};
|
|
4849
5138
|
|
|
4850
|
-
// ../../node_modules/.pnpm/minimatch@10.
|
|
4851
|
-
var unescape = (s, { windowsPathsNoEscape = false } = {}) => {
|
|
4852
|
-
|
|
5139
|
+
// ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/unescape.js
|
|
5140
|
+
var unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
|
|
5141
|
+
if (magicalBraces) {
|
|
5142
|
+
return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
|
|
5143
|
+
}
|
|
5144
|
+
return windowsPathsNoEscape ? s.replace(/\[([^\/\\{}])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\{}])\]/g, "$1$2").replace(/\\([^\/{}])/g, "$1");
|
|
4853
5145
|
};
|
|
4854
5146
|
|
|
4855
|
-
// ../../node_modules/.pnpm/minimatch@10.
|
|
5147
|
+
// ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/ast.js
|
|
4856
5148
|
var types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]);
|
|
4857
5149
|
var isExtglobType = (c) => types.has(c);
|
|
4858
5150
|
var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))";
|
|
@@ -5203,7 +5495,7 @@ var AST = class _AST {
|
|
|
5203
5495
|
if (this.#root === this)
|
|
5204
5496
|
this.#fillNegs();
|
|
5205
5497
|
if (!this.type) {
|
|
5206
|
-
const noEmpty = this.isStart() && this.isEnd();
|
|
5498
|
+
const noEmpty = this.isStart() && this.isEnd() && !this.#parts.some((s) => typeof s !== "string");
|
|
5207
5499
|
const src = this.#parts.map((p) => {
|
|
5208
5500
|
const [re, _, hasMagic2, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
|
|
5209
5501
|
this.#hasMagic = this.#hasMagic || hasMagic2;
|
|
@@ -5313,10 +5605,7 @@ var AST = class _AST {
|
|
|
5313
5605
|
}
|
|
5314
5606
|
}
|
|
5315
5607
|
if (c === "*") {
|
|
5316
|
-
|
|
5317
|
-
re += starNoEmpty;
|
|
5318
|
-
else
|
|
5319
|
-
re += star;
|
|
5608
|
+
re += noEmpty && glob2 === "*" ? starNoEmpty : star;
|
|
5320
5609
|
hasMagic2 = true;
|
|
5321
5610
|
continue;
|
|
5322
5611
|
}
|
|
@@ -5331,12 +5620,15 @@ var AST = class _AST {
|
|
|
5331
5620
|
}
|
|
5332
5621
|
};
|
|
5333
5622
|
|
|
5334
|
-
// ../../node_modules/.pnpm/minimatch@10.
|
|
5335
|
-
var escape = (s, { windowsPathsNoEscape = false } = {}) => {
|
|
5623
|
+
// ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/escape.js
|
|
5624
|
+
var escape = (s, { windowsPathsNoEscape = false, magicalBraces = false } = {}) => {
|
|
5625
|
+
if (magicalBraces) {
|
|
5626
|
+
return windowsPathsNoEscape ? s.replace(/[?*()[\]{}]/g, "[$&]") : s.replace(/[?*()[\]\\{}]/g, "\\$&");
|
|
5627
|
+
}
|
|
5336
5628
|
return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
|
|
5337
5629
|
};
|
|
5338
5630
|
|
|
5339
|
-
// ../../node_modules/.pnpm/minimatch@10.
|
|
5631
|
+
// ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/index.js
|
|
5340
5632
|
var minimatch = (p, pattern, options = {}) => {
|
|
5341
5633
|
assertValidPattern(pattern);
|
|
5342
5634
|
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|
@@ -5973,16 +6265,27 @@ var Minimatch = class {
|
|
|
5973
6265
|
pp[i] = twoStar;
|
|
5974
6266
|
}
|
|
5975
6267
|
} else if (next === void 0) {
|
|
5976
|
-
pp[i - 1] = prev + "(
|
|
6268
|
+
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + ")?";
|
|
5977
6269
|
} else if (next !== GLOBSTAR) {
|
|
5978
6270
|
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
|
|
5979
6271
|
pp[i + 1] = GLOBSTAR;
|
|
5980
6272
|
}
|
|
5981
6273
|
});
|
|
5982
|
-
|
|
6274
|
+
const filtered = pp.filter((p) => p !== GLOBSTAR);
|
|
6275
|
+
if (this.partial && filtered.length >= 1) {
|
|
6276
|
+
const prefixes = [];
|
|
6277
|
+
for (let i = 1; i <= filtered.length; i++) {
|
|
6278
|
+
prefixes.push(filtered.slice(0, i).join("/"));
|
|
6279
|
+
}
|
|
6280
|
+
return "(?:" + prefixes.join("|") + ")";
|
|
6281
|
+
}
|
|
6282
|
+
return filtered.join("/");
|
|
5983
6283
|
}).join("|");
|
|
5984
6284
|
const [open, close] = set.length > 1 ? ["(?:", ")"] : ["", ""];
|
|
5985
6285
|
re = "^" + open + re + close + "$";
|
|
6286
|
+
if (this.partial) {
|
|
6287
|
+
re = "^(?:\\/|" + open + re.slice(1, -1) + close + ")$";
|
|
6288
|
+
}
|
|
5986
6289
|
if (this.negate)
|
|
5987
6290
|
re = "^(?!" + re + ").+$";
|
|
5988
6291
|
try {
|
|
@@ -6054,10 +6357,10 @@ minimatch.Minimatch = Minimatch;
|
|
|
6054
6357
|
minimatch.escape = escape;
|
|
6055
6358
|
minimatch.unescape = unescape;
|
|
6056
6359
|
|
|
6057
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
6058
|
-
import { fileURLToPath as
|
|
6360
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/glob.js
|
|
6361
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6059
6362
|
|
|
6060
|
-
// ../../node_modules/.pnpm/lru-cache@11.2.
|
|
6363
|
+
// ../../node_modules/.pnpm/lru-cache@11.2.2/node_modules/lru-cache/dist/esm/index.js
|
|
6061
6364
|
var defaultPerf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
|
|
6062
6365
|
var warned = /* @__PURE__ */ new Set();
|
|
6063
6366
|
var PROCESS = typeof process === "object" && !!process ? process : {};
|
|
@@ -7103,7 +7406,8 @@ var LRUCache = class _LRUCache {
|
|
|
7103
7406
|
return fetchFail(ac.signal.reason);
|
|
7104
7407
|
}
|
|
7105
7408
|
const bf2 = p;
|
|
7106
|
-
|
|
7409
|
+
const vl = this.#valList[index];
|
|
7410
|
+
if (vl === p || ignoreAbort && updateCache && vl === void 0) {
|
|
7107
7411
|
if (v2 === void 0) {
|
|
7108
7412
|
if (bf2.__staleWhileFetching !== void 0) {
|
|
7109
7413
|
this.#valList[index] = bf2.__staleWhileFetching;
|
|
@@ -7457,9 +7761,9 @@ var LRUCache = class _LRUCache {
|
|
|
7457
7761
|
}
|
|
7458
7762
|
};
|
|
7459
7763
|
|
|
7460
|
-
// ../../node_modules/.pnpm/path-scurry@2.0.
|
|
7764
|
+
// ../../node_modules/.pnpm/path-scurry@2.0.1/node_modules/path-scurry/dist/esm/index.js
|
|
7461
7765
|
import { posix, win32 } from "node:path";
|
|
7462
|
-
import { fileURLToPath } from "node:url";
|
|
7766
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7463
7767
|
import { lstatSync, readdir as readdirCB, readdirSync, readlinkSync, realpathSync as rps } from "fs";
|
|
7464
7768
|
import * as actualFS from "node:fs";
|
|
7465
7769
|
import { lstat, readdir, readlink, realpath } from "node:fs/promises";
|
|
@@ -8342,7 +8646,7 @@ var Minipass = class extends EventEmitter {
|
|
|
8342
8646
|
}
|
|
8343
8647
|
};
|
|
8344
8648
|
|
|
8345
|
-
// ../../node_modules/.pnpm/path-scurry@2.0.
|
|
8649
|
+
// ../../node_modules/.pnpm/path-scurry@2.0.1/node_modules/path-scurry/dist/esm/index.js
|
|
8346
8650
|
var realpathSync = rps.native;
|
|
8347
8651
|
var defaultFS = {
|
|
8348
8652
|
lstatSync,
|
|
@@ -8387,7 +8691,7 @@ var ENOREALPATH = 512;
|
|
|
8387
8691
|
var ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH;
|
|
8388
8692
|
var TYPEMASK = 1023;
|
|
8389
8693
|
var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN;
|
|
8390
|
-
var normalizeCache =
|
|
8694
|
+
var normalizeCache = new LRUCache({ max: 2 ** 12 });
|
|
8391
8695
|
var normalize = (s) => {
|
|
8392
8696
|
const c = normalizeCache.get(s);
|
|
8393
8697
|
if (c)
|
|
@@ -8396,7 +8700,7 @@ var normalize = (s) => {
|
|
|
8396
8700
|
normalizeCache.set(s, n);
|
|
8397
8701
|
return n;
|
|
8398
8702
|
};
|
|
8399
|
-
var normalizeNocaseCache =
|
|
8703
|
+
var normalizeNocaseCache = new LRUCache({ max: 2 ** 12 });
|
|
8400
8704
|
var normalizeNocase = (s) => {
|
|
8401
8705
|
const c = normalizeNocaseCache.get(s);
|
|
8402
8706
|
if (c)
|
|
@@ -8553,6 +8857,7 @@ var PathBase = class {
|
|
|
8553
8857
|
get parentPath() {
|
|
8554
8858
|
return (this.parent || this).fullpath();
|
|
8555
8859
|
}
|
|
8860
|
+
/* c8 ignore start */
|
|
8556
8861
|
/**
|
|
8557
8862
|
* Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively,
|
|
8558
8863
|
* this property refers to the *parent* path, not the path object itself.
|
|
@@ -8562,6 +8867,7 @@ var PathBase = class {
|
|
|
8562
8867
|
get path() {
|
|
8563
8868
|
return this.parentPath;
|
|
8564
8869
|
}
|
|
8870
|
+
/* c8 ignore stop */
|
|
8565
8871
|
/**
|
|
8566
8872
|
* Do not create new Path objects directly. They should always be accessed
|
|
8567
8873
|
* via the PathScurry class or other methods on the Path class.
|
|
@@ -9464,7 +9770,7 @@ var PathScurryBase = class {
|
|
|
9464
9770
|
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS } = {}) {
|
|
9465
9771
|
this.#fs = fsFromOption(fs);
|
|
9466
9772
|
if (cwd instanceof URL || cwd.startsWith("file://")) {
|
|
9467
|
-
cwd =
|
|
9773
|
+
cwd = fileURLToPath2(cwd);
|
|
9468
9774
|
}
|
|
9469
9775
|
const cwdPath = pathImpl.resolve(cwd);
|
|
9470
9776
|
this.roots = /* @__PURE__ */ Object.create(null);
|
|
@@ -10068,7 +10374,7 @@ var PathScurryDarwin = class extends PathScurryPosix {
|
|
|
10068
10374
|
var Path = process.platform === "win32" ? PathWin32 : PathPosix;
|
|
10069
10375
|
var PathScurry = process.platform === "win32" ? PathScurryWin32 : process.platform === "darwin" ? PathScurryDarwin : PathScurryPosix;
|
|
10070
10376
|
|
|
10071
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
10377
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/pattern.js
|
|
10072
10378
|
var isPatternList = (pl) => pl.length >= 1;
|
|
10073
10379
|
var isGlobList = (gl) => gl.length >= 1;
|
|
10074
10380
|
var Pattern = class _Pattern {
|
|
@@ -10233,7 +10539,7 @@ var Pattern = class _Pattern {
|
|
|
10233
10539
|
}
|
|
10234
10540
|
};
|
|
10235
10541
|
|
|
10236
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
10542
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/ignore.js
|
|
10237
10543
|
var defaultPlatform2 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
|
|
10238
10544
|
var Ignore = class {
|
|
10239
10545
|
relative;
|
|
@@ -10320,7 +10626,7 @@ var Ignore = class {
|
|
|
10320
10626
|
}
|
|
10321
10627
|
};
|
|
10322
10628
|
|
|
10323
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
10629
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/processor.js
|
|
10324
10630
|
var HasWalkedCache = class _HasWalkedCache {
|
|
10325
10631
|
store;
|
|
10326
10632
|
constructor(store = /* @__PURE__ */ new Map()) {
|
|
@@ -10541,7 +10847,7 @@ var Processor = class _Processor {
|
|
|
10541
10847
|
}
|
|
10542
10848
|
};
|
|
10543
10849
|
|
|
10544
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
10850
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/walker.js
|
|
10545
10851
|
var makeIgnore = (ignore, opts) => typeof ignore === "string" ? new Ignore([ignore], opts) : Array.isArray(ignore) ? new Ignore(ignore, opts) : ignore;
|
|
10546
10852
|
var GlobUtil = class {
|
|
10547
10853
|
path;
|
|
@@ -10868,7 +11174,7 @@ var GlobStream = class extends GlobUtil {
|
|
|
10868
11174
|
}
|
|
10869
11175
|
};
|
|
10870
11176
|
|
|
10871
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
11177
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/glob.js
|
|
10872
11178
|
var defaultPlatform3 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
|
|
10873
11179
|
var Glob = class {
|
|
10874
11180
|
absolute;
|
|
@@ -10929,7 +11235,7 @@ var Glob = class {
|
|
|
10929
11235
|
if (!opts.cwd) {
|
|
10930
11236
|
this.cwd = "";
|
|
10931
11237
|
} else if (opts.cwd instanceof URL || opts.cwd.startsWith("file://")) {
|
|
10932
|
-
opts.cwd =
|
|
11238
|
+
opts.cwd = fileURLToPath3(opts.cwd);
|
|
10933
11239
|
}
|
|
10934
11240
|
this.cwd = opts.cwd || "";
|
|
10935
11241
|
this.root = opts.root;
|
|
@@ -11068,7 +11374,7 @@ var Glob = class {
|
|
|
11068
11374
|
}
|
|
11069
11375
|
};
|
|
11070
11376
|
|
|
11071
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
11377
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/has-magic.js
|
|
11072
11378
|
var hasMagic = (pattern, options = {}) => {
|
|
11073
11379
|
if (!Array.isArray(pattern)) {
|
|
11074
11380
|
pattern = [pattern];
|
|
@@ -11080,7 +11386,7 @@ var hasMagic = (pattern, options = {}) => {
|
|
|
11080
11386
|
return false;
|
|
11081
11387
|
};
|
|
11082
11388
|
|
|
11083
|
-
// ../../node_modules/.pnpm/glob@11.0
|
|
11389
|
+
// ../../node_modules/.pnpm/glob@11.1.0/node_modules/glob/dist/esm/index.js
|
|
11084
11390
|
function globStreamSync(pattern, options = {}) {
|
|
11085
11391
|
return new Glob(pattern, options).streamSync();
|
|
11086
11392
|
}
|
|
@@ -11242,7 +11548,7 @@ async function analyzeComponentFile(filePath, _options = {}) {
|
|
|
11242
11548
|
});
|
|
11243
11549
|
return analysis;
|
|
11244
11550
|
}
|
|
11245
|
-
const content =
|
|
11551
|
+
const content = readFileSync4(resolve3(filePath), "utf-8");
|
|
11246
11552
|
analysis.size = Buffer.byteLength(content, "utf8");
|
|
11247
11553
|
analysis.lines = content.split("\n").length;
|
|
11248
11554
|
const syntaxAnalysis = analyzeSyntax(content, filePath);
|
|
@@ -11603,7 +11909,7 @@ async function analyzeHydration(options = {}) {
|
|
|
11603
11909
|
}
|
|
11604
11910
|
|
|
11605
11911
|
// src/validators/project-validator.js
|
|
11606
|
-
import { existsSync as existsSync9, readFileSync as
|
|
11912
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
|
|
11607
11913
|
import { resolve as resolve4 } from "path";
|
|
11608
11914
|
async function validateProject(_options = {}) {
|
|
11609
11915
|
const validation = {
|
|
@@ -11670,7 +11976,7 @@ function validatePackageJson() {
|
|
|
11670
11976
|
const issues = [];
|
|
11671
11977
|
const recommendations = [];
|
|
11672
11978
|
try {
|
|
11673
|
-
const packageJson = JSON.parse(
|
|
11979
|
+
const packageJson = JSON.parse(readFileSync5("package.json", "utf-8"));
|
|
11674
11980
|
const requiredFields = ["name", "version", "description"];
|
|
11675
11981
|
requiredFields.forEach((field) => {
|
|
11676
11982
|
const hasField = packageJson[field];
|
|
@@ -11954,7 +12260,7 @@ async function analyzeConfiguration(_options = {}) {
|
|
|
11954
12260
|
};
|
|
11955
12261
|
if (existsSync10("package.json")) {
|
|
11956
12262
|
try {
|
|
11957
|
-
const packageJson = JSON.parse(
|
|
12263
|
+
const packageJson = JSON.parse(readFileSync6("package.json", "utf-8"));
|
|
11958
12264
|
const hasCoherentDeps = Object.keys(packageJson.dependencies || {}).some((dep) => dep.startsWith("@coherent.js/"));
|
|
11959
12265
|
if (!hasCoherentDeps) {
|
|
11960
12266
|
analysis.summary.issues.push("No Coherent.js dependencies found");
|
|
@@ -12098,12 +12404,12 @@ async function generateHTMLReport(result) {
|
|
|
12098
12404
|
}
|
|
12099
12405
|
|
|
12100
12406
|
// src/index.js
|
|
12101
|
-
var __filename =
|
|
12102
|
-
var __dirname =
|
|
12407
|
+
var __filename = fileURLToPath4(import.meta.url);
|
|
12408
|
+
var __dirname = dirname3(__filename);
|
|
12103
12409
|
var version = "1.0.1";
|
|
12104
12410
|
try {
|
|
12105
|
-
const packagePath =
|
|
12106
|
-
const packageJson = JSON.parse(
|
|
12411
|
+
const packagePath = join8(__dirname, "..", "package.json");
|
|
12412
|
+
const packageJson = JSON.parse(readFileSync7(packagePath, "utf-8"));
|
|
12107
12413
|
version = packageJson.version;
|
|
12108
12414
|
} catch {
|
|
12109
12415
|
}
|