@julien-lin/universal-pwa-core 1.3.17 → 1.3.20

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/index.cjs CHANGED
@@ -178,6 +178,9 @@ __export(index_exports, {
178
178
  injectMetaTags: () => injectMetaTags,
179
179
  injectMetaTagsInFile: () => injectMetaTagsInFile,
180
180
  injectMetaTagsInFilesBatch: () => injectMetaTagsInFilesBatch,
181
+ injectNextJsMetadata: () => injectNextJsMetadata,
182
+ injectNextJsMetadataInFile: () => injectNextJsMetadataInFile,
183
+ isNextJsLayoutFile: () => isNextJsLayoutFile,
181
184
  loadConfig: () => loadConfig,
182
185
  mapBackendManifestVarsToOptions: () => mapBackendManifestVarsToOptions,
183
186
  optimizeImage: () => optimizeImage,
@@ -988,7 +991,9 @@ function detectProjectConfiguration(projectPath) {
988
991
  const packageJsonPath = (0, import_path.join)(projectPath, "package.json");
989
992
  if ((0, import_fs.existsSync)(packageJsonPath)) {
990
993
  try {
991
- const packageContent = JSON.parse((0, import_fs.readFileSync)(packageJsonPath, "utf-8"));
994
+ const packageContent = JSON.parse(
995
+ (0, import_fs.readFileSync)(packageJsonPath, "utf-8")
996
+ );
992
997
  const dependencies = {
993
998
  ...packageContent.dependencies ?? {},
994
999
  ...packageContent.devDependencies ?? {}
@@ -1039,7 +1044,9 @@ function detectProjectConfiguration(projectPath) {
1039
1044
  config.buildTool = "vite";
1040
1045
  } else if (dependencies.webpack || Object.keys(dependencies).some((key) => key.startsWith("webpack-"))) {
1041
1046
  config.buildTool = "webpack";
1042
- } else if (dependencies.rollup || Object.keys(dependencies).some((key) => key.startsWith("rollup-plugin-"))) {
1047
+ } else if (dependencies.rollup || Object.keys(dependencies).some(
1048
+ (key) => key.startsWith("rollup-plugin-")
1049
+ )) {
1043
1050
  config.buildTool = "rollup";
1044
1051
  } else if (dependencies.esbuild) {
1045
1052
  config.buildTool = "esbuild";
@@ -1054,7 +1061,11 @@ function detectProjectConfiguration(projectPath) {
1054
1061
  return config;
1055
1062
  }
1056
1063
  function createResult(framework, confidence, indicators, version = null, configuration = null) {
1057
- const confidenceScore = calculateConfidenceScore(framework, confidence, indicators);
1064
+ const confidenceScore = calculateConfidenceScore(
1065
+ framework,
1066
+ confidence,
1067
+ indicators
1068
+ );
1058
1069
  const finalConfidence = scoreToConfidence(confidenceScore);
1059
1070
  const finalConfig = configuration ?? {
1060
1071
  language: null,
@@ -1085,7 +1096,13 @@ function detectFramework(projectPath) {
1085
1096
  indicators.push("wp-content/plugins/woocommerce/");
1086
1097
  framework = "woocommerce";
1087
1098
  confidence = "high";
1088
- return createResult(framework, confidence, indicators, null, projectConfig);
1099
+ return createResult(
1100
+ framework,
1101
+ confidence,
1102
+ indicators,
1103
+ null,
1104
+ projectConfig
1105
+ );
1089
1106
  }
1090
1107
  framework = "wordpress";
1091
1108
  confidence = "high";
@@ -1097,7 +1114,13 @@ function detectFramework(projectPath) {
1097
1114
  indicators.push("themes/");
1098
1115
  framework = "drupal";
1099
1116
  confidence = "high";
1100
- return createResult(framework, confidence, indicators, null, projectConfig);
1117
+ return createResult(
1118
+ framework,
1119
+ confidence,
1120
+ indicators,
1121
+ null,
1122
+ projectConfig
1123
+ );
1101
1124
  }
1102
1125
  }
1103
1126
  if (hasFileAndDirectory(projectPath, "configuration.php", "administrator")) {
@@ -1115,7 +1138,9 @@ function detectFramework(projectPath) {
1115
1138
  const composerPath = (0, import_path.join)(projectPath, "composer.json");
1116
1139
  if ((0, import_fs.existsSync)(composerPath)) {
1117
1140
  try {
1118
- const composerContent = JSON.parse((0, import_fs.readFileSync)(composerPath, "utf-8"));
1141
+ const composerContent = JSON.parse(
1142
+ (0, import_fs.readFileSync)(composerPath, "utf-8")
1143
+ );
1119
1144
  const dependencies = {
1120
1145
  ...composerContent.require ?? {},
1121
1146
  ...composerContent["require-dev"] ?? {}
@@ -1126,7 +1151,13 @@ function detectFramework(projectPath) {
1126
1151
  indicators.push("app/ and pub/");
1127
1152
  framework = "magento";
1128
1153
  confidence = "high";
1129
- return createResult(framework, confidence, indicators, null, projectConfig);
1154
+ return createResult(
1155
+ framework,
1156
+ confidence,
1157
+ indicators,
1158
+ null,
1159
+ projectConfig
1160
+ );
1130
1161
  }
1131
1162
  }
1132
1163
  if (dependencies["prestashop/prestashop"]) {
@@ -1135,7 +1166,13 @@ function detectFramework(projectPath) {
1135
1166
  indicators.push("config/ and themes/");
1136
1167
  framework = "prestashop";
1137
1168
  confidence = "high";
1138
- return createResult(framework, confidence, indicators, null, projectConfig);
1169
+ return createResult(
1170
+ framework,
1171
+ confidence,
1172
+ indicators,
1173
+ null,
1174
+ projectConfig
1175
+ );
1139
1176
  }
1140
1177
  }
1141
1178
  if (dependencies["symfony/symfony"] || dependencies["symfony/framework-bundle"]) {
@@ -1144,7 +1181,13 @@ function detectFramework(projectPath) {
1144
1181
  indicators.push("public/");
1145
1182
  framework = "symfony";
1146
1183
  confidence = "high";
1147
- return createResult(framework, confidence, indicators, null, projectConfig);
1184
+ return createResult(
1185
+ framework,
1186
+ confidence,
1187
+ indicators,
1188
+ null,
1189
+ projectConfig
1190
+ );
1148
1191
  }
1149
1192
  }
1150
1193
  if (dependencies["laravel/framework"]) {
@@ -1153,7 +1196,13 @@ function detectFramework(projectPath) {
1153
1196
  indicators.push("public/");
1154
1197
  framework = "laravel";
1155
1198
  confidence = "high";
1156
- return createResult(framework, confidence, indicators, null, projectConfig);
1199
+ return createResult(
1200
+ framework,
1201
+ confidence,
1202
+ indicators,
1203
+ null,
1204
+ projectConfig
1205
+ );
1157
1206
  }
1158
1207
  }
1159
1208
  if (dependencies["codeigniter4/framework"]) {
@@ -1162,7 +1211,13 @@ function detectFramework(projectPath) {
1162
1211
  indicators.push("public/");
1163
1212
  framework = "codeigniter";
1164
1213
  confidence = "high";
1165
- return createResult(framework, confidence, indicators, null, projectConfig);
1214
+ return createResult(
1215
+ framework,
1216
+ confidence,
1217
+ indicators,
1218
+ null,
1219
+ projectConfig
1220
+ );
1166
1221
  }
1167
1222
  }
1168
1223
  if (dependencies["cakephp/cakephp"]) {
@@ -1171,7 +1226,13 @@ function detectFramework(projectPath) {
1171
1226
  indicators.push("webroot/ or public/");
1172
1227
  framework = "cakephp";
1173
1228
  confidence = "high";
1174
- return createResult(framework, confidence, indicators, null, projectConfig);
1229
+ return createResult(
1230
+ framework,
1231
+ confidence,
1232
+ indicators,
1233
+ null,
1234
+ projectConfig
1235
+ );
1175
1236
  }
1176
1237
  }
1177
1238
  if (dependencies["yiisoft/yii2"] || dependencies["yiisoft/yii"]) {
@@ -1180,7 +1241,13 @@ function detectFramework(projectPath) {
1180
1241
  indicators.push("web/ or public/");
1181
1242
  framework = "yii";
1182
1243
  confidence = "high";
1183
- return createResult(framework, confidence, indicators, null, projectConfig);
1244
+ return createResult(
1245
+ framework,
1246
+ confidence,
1247
+ indicators,
1248
+ null,
1249
+ projectConfig
1250
+ );
1184
1251
  }
1185
1252
  }
1186
1253
  if (dependencies["laminas/laminas-mvc"] || dependencies["laminas/laminas-component-installer"]) {
@@ -1189,7 +1256,13 @@ function detectFramework(projectPath) {
1189
1256
  indicators.push("public/");
1190
1257
  framework = "laminas";
1191
1258
  confidence = "high";
1192
- return createResult(framework, confidence, indicators, null, projectConfig);
1259
+ return createResult(
1260
+ framework,
1261
+ confidence,
1262
+ indicators,
1263
+ null,
1264
+ projectConfig
1265
+ );
1193
1266
  }
1194
1267
  }
1195
1268
  } catch {
@@ -1198,18 +1271,47 @@ function detectFramework(projectPath) {
1198
1271
  const packageJsonPath = (0, import_path.join)(projectPath, "package.json");
1199
1272
  if ((0, import_fs.existsSync)(packageJsonPath)) {
1200
1273
  try {
1201
- const packageContent = JSON.parse((0, import_fs.readFileSync)(packageJsonPath, "utf-8"));
1274
+ const packageContent = JSON.parse(
1275
+ (0, import_fs.readFileSync)(packageJsonPath, "utf-8")
1276
+ );
1202
1277
  const dependencies = {
1203
1278
  ...packageContent.dependencies ?? {},
1204
1279
  ...packageContent.devDependencies ?? {}
1205
1280
  };
1206
1281
  if (dependencies.next) {
1207
1282
  indicators.push("package.json: next");
1283
+ const appLayoutPaths = [
1284
+ (0, import_path.join)(projectPath, "src", "app", "layout.tsx"),
1285
+ (0, import_path.join)(projectPath, "src", "app", "layout.ts"),
1286
+ (0, import_path.join)(projectPath, "app", "layout.tsx"),
1287
+ (0, import_path.join)(projectPath, "app", "layout.ts")
1288
+ ];
1289
+ const hasAppLayout = appLayoutPaths.some((path) => (0, import_fs.existsSync)(path));
1290
+ if (hasAppLayout) {
1291
+ indicators.push("App Router detected (app/layout.tsx)");
1292
+ }
1208
1293
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, ".next"))) {
1209
1294
  indicators.push(".next/");
1210
1295
  framework = "nextjs";
1211
1296
  confidence = "high";
1212
- return createResult(framework, confidence, indicators, null, projectConfig);
1297
+ return createResult(
1298
+ framework,
1299
+ confidence,
1300
+ indicators,
1301
+ null,
1302
+ projectConfig
1303
+ );
1304
+ }
1305
+ if (hasAppLayout) {
1306
+ framework = "nextjs";
1307
+ confidence = "high";
1308
+ return createResult(
1309
+ framework,
1310
+ confidence,
1311
+ indicators,
1312
+ null,
1313
+ projectConfig
1314
+ );
1213
1315
  }
1214
1316
  }
1215
1317
  if (dependencies.nuxt) {
@@ -1218,7 +1320,13 @@ function detectFramework(projectPath) {
1218
1320
  indicators.push(".nuxt/");
1219
1321
  framework = "nuxt";
1220
1322
  confidence = "high";
1221
- return createResult(framework, confidence, indicators, null, projectConfig);
1323
+ return createResult(
1324
+ framework,
1325
+ confidence,
1326
+ indicators,
1327
+ null,
1328
+ projectConfig
1329
+ );
1222
1330
  }
1223
1331
  }
1224
1332
  if (dependencies.react) {
@@ -1227,7 +1335,9 @@ function detectFramework(projectPath) {
1227
1335
  confidence = framework ? "high" : "medium";
1228
1336
  const version = detectFrameworkVersion("react", dependencies);
1229
1337
  if (version) {
1230
- indicators.push(`React version: ${version.major}.${version.minor ?? "x"}.${version.patch ?? "x"}`);
1338
+ indicators.push(
1339
+ `React version: ${version.major}.${version.minor ?? "x"}.${version.patch ?? "x"}`
1340
+ );
1231
1341
  }
1232
1342
  }
1233
1343
  if (dependencies.vue) {
@@ -1237,7 +1347,9 @@ function detectFramework(projectPath) {
1237
1347
  confidence = "high";
1238
1348
  const version = detectFrameworkVersion("vue", dependencies);
1239
1349
  if (version) {
1240
- indicators.push(`Vue version: ${version.major}.${version.minor ?? "x"}.${version.patch ?? "x"}`);
1350
+ indicators.push(
1351
+ `Vue version: ${version.major}.${version.minor ?? "x"}.${version.patch ?? "x"}`
1352
+ );
1241
1353
  }
1242
1354
  }
1243
1355
  }
@@ -1248,7 +1360,9 @@ function detectFramework(projectPath) {
1248
1360
  confidence = "high";
1249
1361
  const version = detectFrameworkVersion("angular", dependencies);
1250
1362
  if (version) {
1251
- indicators.push(`Angular version: ${version.major}.${version.minor ?? "x"}.${version.patch ?? "x"}`);
1363
+ indicators.push(
1364
+ `Angular version: ${version.major}.${version.minor ?? "x"}.${version.patch ?? "x"}`
1365
+ );
1252
1366
  }
1253
1367
  }
1254
1368
  }
@@ -1258,7 +1372,13 @@ function detectFramework(projectPath) {
1258
1372
  indicators.push(".svelte-kit/");
1259
1373
  framework = "sveltekit";
1260
1374
  confidence = "high";
1261
- return createResult(framework, confidence, indicators, null, projectConfig);
1375
+ return createResult(
1376
+ framework,
1377
+ confidence,
1378
+ indicators,
1379
+ null,
1380
+ projectConfig
1381
+ );
1262
1382
  }
1263
1383
  }
1264
1384
  if (dependencies.svelte && !dependencies["@sveltejs/kit"]) {
@@ -1274,7 +1394,13 @@ function detectFramework(projectPath) {
1274
1394
  indicators.push("app/");
1275
1395
  framework = "remix";
1276
1396
  confidence = "high";
1277
- return createResult(framework, confidence, indicators, null, projectConfig);
1397
+ return createResult(
1398
+ framework,
1399
+ confidence,
1400
+ indicators,
1401
+ null,
1402
+ projectConfig
1403
+ );
1278
1404
  }
1279
1405
  }
1280
1406
  if (dependencies.astro) {
@@ -1283,7 +1409,13 @@ function detectFramework(projectPath) {
1283
1409
  indicators.push(".astro/");
1284
1410
  framework = "astro";
1285
1411
  confidence = "high";
1286
- return createResult(framework, confidence, indicators, null, projectConfig);
1412
+ return createResult(
1413
+ framework,
1414
+ confidence,
1415
+ indicators,
1416
+ null,
1417
+ projectConfig
1418
+ );
1287
1419
  }
1288
1420
  }
1289
1421
  if (dependencies["solid-js"]) {
@@ -1301,13 +1433,25 @@ function detectFramework(projectPath) {
1301
1433
  indicators.push("manage.py and settings.py (Django)");
1302
1434
  framework = "django";
1303
1435
  confidence = "high";
1304
- return createResult(framework, confidence, indicators, null, projectConfig);
1436
+ return createResult(
1437
+ framework,
1438
+ confidence,
1439
+ indicators,
1440
+ null,
1441
+ projectConfig
1442
+ );
1305
1443
  }
1306
1444
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "manage.py")) && (0, import_fs.existsSync)((0, import_path.join)(projectPath, "django"))) {
1307
1445
  indicators.push("manage.py and django/ (Django)");
1308
1446
  framework = "django";
1309
1447
  confidence = "high";
1310
- return createResult(framework, confidence, indicators, null, projectConfig);
1448
+ return createResult(
1449
+ framework,
1450
+ confidence,
1451
+ indicators,
1452
+ null,
1453
+ projectConfig
1454
+ );
1311
1455
  }
1312
1456
  const requirementsPath = (0, import_path.join)(projectPath, "requirements.txt");
1313
1457
  if ((0, import_fs.existsSync)(requirementsPath)) {
@@ -1319,14 +1463,26 @@ function detectFramework(projectPath) {
1319
1463
  indicators.push("app.py or application.py");
1320
1464
  framework = "flask";
1321
1465
  confidence = "high";
1322
- return createResult(framework, confidence, indicators, null, projectConfig);
1466
+ return createResult(
1467
+ framework,
1468
+ confidence,
1469
+ indicators,
1470
+ null,
1471
+ projectConfig
1472
+ );
1323
1473
  }
1324
1474
  }
1325
1475
  if (requirementsContent.includes("fastapi") || requirementsContent.includes("FastAPI")) {
1326
1476
  indicators.push("requirements.txt: FastAPI");
1327
1477
  framework = "fastapi";
1328
1478
  confidence = "high";
1329
- return createResult(framework, confidence, indicators, null, projectConfig);
1479
+ return createResult(
1480
+ framework,
1481
+ confidence,
1482
+ indicators,
1483
+ null,
1484
+ projectConfig
1485
+ );
1330
1486
  }
1331
1487
  } catch {
1332
1488
  }
@@ -1343,7 +1499,13 @@ function detectFramework(projectPath) {
1343
1499
  indicators.push("config/application.rb or config/routes.rb");
1344
1500
  framework = "rails";
1345
1501
  confidence = "high";
1346
- return createResult(framework, confidence, indicators, null, projectConfig);
1502
+ return createResult(
1503
+ framework,
1504
+ confidence,
1505
+ indicators,
1506
+ null,
1507
+ projectConfig
1508
+ );
1347
1509
  }
1348
1510
  }
1349
1511
  if (gemfileContent.includes("gem 'sinatra'") || gemfileContent.includes('gem "sinatra"')) {
@@ -1352,7 +1514,13 @@ function detectFramework(projectPath) {
1352
1514
  indicators.push("app.rb or main.rb");
1353
1515
  framework = "sinatra";
1354
1516
  confidence = "high";
1355
- return createResult(framework, confidence, indicators, null, projectConfig);
1517
+ return createResult(
1518
+ framework,
1519
+ confidence,
1520
+ indicators,
1521
+ null,
1522
+ projectConfig
1523
+ );
1356
1524
  }
1357
1525
  }
1358
1526
  } catch {
@@ -1372,7 +1540,13 @@ function detectFramework(projectPath) {
1372
1540
  indicators.push("go.mod and main.go with HTTP server");
1373
1541
  framework = "go";
1374
1542
  confidence = "high";
1375
- return createResult(framework, confidence, indicators, null, projectConfig);
1543
+ return createResult(
1544
+ framework,
1545
+ confidence,
1546
+ indicators,
1547
+ null,
1548
+ projectConfig
1549
+ );
1376
1550
  }
1377
1551
  } catch {
1378
1552
  }
@@ -1385,7 +1559,13 @@ function detectFramework(projectPath) {
1385
1559
  indicators.push("go.mod and server.go with HTTP server");
1386
1560
  framework = "go";
1387
1561
  confidence = "high";
1388
- return createResult(framework, confidence, indicators, null, projectConfig);
1562
+ return createResult(
1563
+ framework,
1564
+ confidence,
1565
+ indicators,
1566
+ null,
1567
+ projectConfig
1568
+ );
1389
1569
  }
1390
1570
  } catch {
1391
1571
  }
@@ -1405,7 +1585,13 @@ function detectFramework(projectPath) {
1405
1585
  indicators.push("pom.xml: spring-boot");
1406
1586
  framework = "spring";
1407
1587
  confidence = "high";
1408
- return createResult(framework, confidence, indicators, null, projectConfig);
1588
+ return createResult(
1589
+ framework,
1590
+ confidence,
1591
+ indicators,
1592
+ null,
1593
+ projectConfig
1594
+ );
1409
1595
  }
1410
1596
  } catch {
1411
1597
  }
@@ -1417,7 +1603,13 @@ function detectFramework(projectPath) {
1417
1603
  indicators.push("build.gradle: spring-boot");
1418
1604
  framework = "spring";
1419
1605
  confidence = "high";
1420
- return createResult(framework, confidence, indicators, null, projectConfig);
1606
+ return createResult(
1607
+ framework,
1608
+ confidence,
1609
+ indicators,
1610
+ null,
1611
+ projectConfig
1612
+ );
1421
1613
  }
1422
1614
  } catch {
1423
1615
  }
@@ -1425,7 +1617,10 @@ function detectFramework(projectPath) {
1425
1617
  }
1426
1618
  if (!framework) {
1427
1619
  try {
1428
- const csprojMatches = (0, import_glob.globSync)("*.csproj", { cwd: projectPath, absolute: false });
1620
+ const csprojMatches = (0, import_glob.globSync)("*.csproj", {
1621
+ cwd: projectPath,
1622
+ absolute: false
1623
+ });
1429
1624
  if (csprojMatches.length > 0) {
1430
1625
  const firstCsproj = (0, import_path.join)(projectPath, csprojMatches[0]);
1431
1626
  try {
@@ -1436,7 +1631,13 @@ function detectFramework(projectPath) {
1436
1631
  indicators.push("Program.cs or Startup.cs");
1437
1632
  framework = "aspnet";
1438
1633
  confidence = "high";
1439
- return createResult(framework, confidence, indicators, null, projectConfig);
1634
+ return createResult(
1635
+ framework,
1636
+ confidence,
1637
+ indicators,
1638
+ null,
1639
+ projectConfig
1640
+ );
1440
1641
  }
1441
1642
  }
1442
1643
  } catch {
@@ -1452,71 +1653,149 @@ function detectFramework(projectPath) {
1452
1653
  indicators.push("_posts/");
1453
1654
  framework = "jekyll";
1454
1655
  confidence = "high";
1455
- return createResult(framework, confidence, indicators, null, projectConfig);
1656
+ return createResult(
1657
+ framework,
1658
+ confidence,
1659
+ indicators,
1660
+ null,
1661
+ projectConfig
1662
+ );
1456
1663
  }
1457
1664
  framework = "jekyll";
1458
1665
  confidence = "medium";
1459
- return createResult(framework, confidence, indicators, null, projectConfig);
1666
+ return createResult(
1667
+ framework,
1668
+ confidence,
1669
+ indicators,
1670
+ null,
1671
+ projectConfig
1672
+ );
1460
1673
  }
1461
- const hugoConfigFiles = ["config.toml", "config.yaml", "config.yml", "hugo.toml", "hugo.yaml", "hugo.yml"];
1462
- const hasHugoConfig = hugoConfigFiles.some((file) => (0, import_fs.existsSync)((0, import_path.join)(projectPath, file)));
1674
+ const hugoConfigFiles = [
1675
+ "config.toml",
1676
+ "config.yaml",
1677
+ "config.yml",
1678
+ "hugo.toml",
1679
+ "hugo.yaml",
1680
+ "hugo.yml"
1681
+ ];
1682
+ const hasHugoConfig = hugoConfigFiles.some(
1683
+ (file) => (0, import_fs.existsSync)((0, import_path.join)(projectPath, file))
1684
+ );
1463
1685
  if (hasHugoConfig) {
1464
1686
  indicators.push("Hugo config file found");
1465
1687
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "content")) && (0, import_fs.existsSync)((0, import_path.join)(projectPath, "layouts"))) {
1466
1688
  indicators.push("content/ and layouts/");
1467
1689
  framework = "hugo";
1468
1690
  confidence = "high";
1469
- return createResult(framework, confidence, indicators, null, projectConfig);
1691
+ return createResult(
1692
+ framework,
1693
+ confidence,
1694
+ indicators,
1695
+ null,
1696
+ projectConfig
1697
+ );
1470
1698
  }
1471
1699
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "content"))) {
1472
1700
  indicators.push("content/");
1473
1701
  framework = "hugo";
1474
1702
  confidence = "high";
1475
- return createResult(framework, confidence, indicators, null, projectConfig);
1703
+ return createResult(
1704
+ framework,
1705
+ confidence,
1706
+ indicators,
1707
+ null,
1708
+ projectConfig
1709
+ );
1476
1710
  }
1477
1711
  }
1478
1712
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "gatsby-config.js")) || (0, import_fs.existsSync)((0, import_path.join)(projectPath, "gatsby-config.ts"))) {
1479
1713
  indicators.push("gatsby-config.js/ts (Gatsby)");
1480
1714
  framework = "gatsby";
1481
1715
  confidence = "high";
1482
- return createResult(framework, confidence, indicators, null, projectConfig);
1716
+ return createResult(
1717
+ framework,
1718
+ confidence,
1719
+ indicators,
1720
+ null,
1721
+ projectConfig
1722
+ );
1483
1723
  }
1484
- const eleventyFiles = [".eleventy.js", ".eleventy.cjs", "eleventy.config.js", "eleventy.config.cjs"];
1485
- const hasEleventyConfig = eleventyFiles.some((file) => (0, import_fs.existsSync)((0, import_path.join)(projectPath, file)));
1724
+ const eleventyFiles = [
1725
+ ".eleventy.js",
1726
+ ".eleventy.cjs",
1727
+ "eleventy.config.js",
1728
+ "eleventy.config.cjs"
1729
+ ];
1730
+ const hasEleventyConfig = eleventyFiles.some(
1731
+ (file) => (0, import_fs.existsSync)((0, import_path.join)(projectPath, file))
1732
+ );
1486
1733
  if (hasEleventyConfig) {
1487
1734
  indicators.push("Eleventy config file found");
1488
1735
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "_data"))) {
1489
1736
  indicators.push("_data/");
1490
1737
  framework = "eleventy";
1491
1738
  confidence = "high";
1492
- return createResult(framework, confidence, indicators, null, projectConfig);
1739
+ return createResult(
1740
+ framework,
1741
+ confidence,
1742
+ indicators,
1743
+ null,
1744
+ projectConfig
1745
+ );
1493
1746
  }
1494
1747
  framework = "eleventy";
1495
1748
  confidence = "high";
1496
- return createResult(framework, confidence, indicators, null, projectConfig);
1749
+ return createResult(
1750
+ framework,
1751
+ confidence,
1752
+ indicators,
1753
+ null,
1754
+ projectConfig
1755
+ );
1497
1756
  }
1498
1757
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "vitepress.config.js")) || (0, import_fs.existsSync)((0, import_path.join)(projectPath, "vitepress.config.ts"))) {
1499
1758
  indicators.push("vitepress.config.js/ts (VitePress)");
1500
1759
  framework = "vitepress";
1501
1760
  confidence = "high";
1502
- return createResult(framework, confidence, indicators, null, projectConfig);
1761
+ return createResult(
1762
+ framework,
1763
+ confidence,
1764
+ indicators,
1765
+ null,
1766
+ projectConfig
1767
+ );
1503
1768
  }
1504
1769
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "docs", ".vitepress", "config.js")) || (0, import_fs.existsSync)((0, import_path.join)(projectPath, "docs", ".vitepress", "config.ts"))) {
1505
1770
  indicators.push("docs/.vitepress/config.js/ts (VitePress)");
1506
1771
  framework = "vitepress";
1507
1772
  confidence = "high";
1508
- return createResult(framework, confidence, indicators, null, projectConfig);
1773
+ return createResult(
1774
+ framework,
1775
+ confidence,
1776
+ indicators,
1777
+ null,
1778
+ projectConfig
1779
+ );
1509
1780
  }
1510
1781
  if ((0, import_fs.existsSync)((0, import_path.join)(projectPath, "docusaurus.config.js")) || (0, import_fs.existsSync)((0, import_path.join)(projectPath, "docusaurus.config.ts"))) {
1511
1782
  indicators.push("docusaurus.config.js/ts (Docusaurus)");
1512
1783
  framework = "docusaurus";
1513
1784
  confidence = "high";
1514
- return createResult(framework, confidence, indicators, null, projectConfig);
1785
+ return createResult(
1786
+ framework,
1787
+ confidence,
1788
+ indicators,
1789
+ null,
1790
+ projectConfig
1791
+ );
1515
1792
  }
1516
1793
  }
1517
1794
  if (!framework) {
1518
1795
  const htmlFiles = ["index.html", "index.htm"];
1519
- const hasHtml = htmlFiles.some((file) => (0, import_fs.existsSync)((0, import_path.join)(projectPath, file)));
1796
+ const hasHtml = htmlFiles.some(
1797
+ (file) => (0, import_fs.existsSync)((0, import_path.join)(projectPath, file))
1798
+ );
1520
1799
  if (hasHtml) {
1521
1800
  indicators.push("HTML files present");
1522
1801
  framework = "static";
@@ -1528,7 +1807,9 @@ function detectFramework(projectPath) {
1528
1807
  const packageJsonPath2 = (0, import_path.join)(projectPath, "package.json");
1529
1808
  if ((0, import_fs.existsSync)(packageJsonPath2)) {
1530
1809
  try {
1531
- const packageContent = JSON.parse((0, import_fs.readFileSync)(packageJsonPath2, "utf-8"));
1810
+ const packageContent = JSON.parse(
1811
+ (0, import_fs.readFileSync)(packageJsonPath2, "utf-8")
1812
+ );
1532
1813
  const dependencies = {
1533
1814
  ...packageContent.dependencies ?? {},
1534
1815
  ...packageContent.devDependencies ?? {}
@@ -1545,12 +1826,20 @@ function detectFramework(projectPath) {
1545
1826
  indicators.push(`CSS-in-JS: ${projectConfig.cssInJs.join(", ")}`);
1546
1827
  }
1547
1828
  if (projectConfig.stateManagement.length > 0) {
1548
- indicators.push(`State Management: ${projectConfig.stateManagement.join(", ")}`);
1829
+ indicators.push(
1830
+ `State Management: ${projectConfig.stateManagement.join(", ")}`
1831
+ );
1549
1832
  }
1550
1833
  if (projectConfig.buildTool) {
1551
1834
  indicators.push(`Build Tool: ${projectConfig.buildTool}`);
1552
1835
  }
1553
- return createResult(framework, confidence, indicators, detectedVersion, projectConfig);
1836
+ return createResult(
1837
+ framework,
1838
+ confidence,
1839
+ indicators,
1840
+ detectedVersion,
1841
+ projectConfig
1842
+ );
1554
1843
  }
1555
1844
 
1556
1845
  // src/scanner/asset-detector.ts
@@ -2570,7 +2859,16 @@ var ManifestSchema = import_zod.z.object({
2570
2859
  start_url: import_zod.z.string().default("/"),
2571
2860
  scope: import_zod.z.string().default("/"),
2572
2861
  display: import_zod.z.enum(["standalone", "fullscreen", "minimal-ui", "browser"]).default("standalone"),
2573
- orientation: import_zod.z.enum(["any", "portrait", "landscape"]).optional(),
2862
+ orientation: import_zod.z.enum([
2863
+ "any",
2864
+ "natural",
2865
+ "portrait",
2866
+ "portrait-primary",
2867
+ "portrait-secondary",
2868
+ "landscape",
2869
+ "landscape-primary",
2870
+ "landscape-secondary"
2871
+ ]).optional(),
2574
2872
  theme_color: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
2575
2873
  background_color: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
2576
2874
  icons: import_zod.z.array(ManifestIconSchema).min(1),
@@ -5735,14 +6033,173 @@ async function injectMetaTagsInFilesBatch(batchOptions) {
5735
6033
  };
5736
6034
  }
5737
6035
 
5738
- // src/validator/pwa-validator.ts
6036
+ // src/injector/nextjs-metadata-injector.ts
5739
6037
  var import_fs14 = require("fs");
6038
+ function isNextJsLayoutFile(filePath) {
6039
+ const fileName = filePath.split("/").pop() || "";
6040
+ return /^layout\.(tsx?|jsx?)$/.test(fileName);
6041
+ }
6042
+ function buildManifestPath(manifestPath, basePath) {
6043
+ if (!manifestPath) return "";
6044
+ let path = manifestPath.startsWith("/") ? manifestPath : `/${manifestPath}`;
6045
+ if (basePath && basePath !== "/") {
6046
+ const basePathTrimmed = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
6047
+ const finalBasePath = basePathTrimmed.startsWith("/") ? basePathTrimmed : `/${basePathTrimmed}`;
6048
+ const pathTrimmed = path.startsWith("/") ? path.slice(1) : path;
6049
+ path = `${finalBasePath}/${pathTrimmed}`;
6050
+ }
6051
+ return path;
6052
+ }
6053
+ function findMetadataExport(content) {
6054
+ const metadataPattern = /export\s+const\s+metadata\s*:\s*Metadata\s*=\s*(\{[\s\S]*?\})/;
6055
+ const match = content.match(metadataPattern);
6056
+ if (match) {
6057
+ return {
6058
+ found: true,
6059
+ startIndex: match.index || 0,
6060
+ endIndex: (match.index || 0) + match[0].length,
6061
+ isObject: true,
6062
+ content: match[1]
6063
+ };
6064
+ }
6065
+ return {
6066
+ found: false,
6067
+ startIndex: -1,
6068
+ endIndex: -1,
6069
+ isObject: false,
6070
+ content: ""
6071
+ };
6072
+ }
6073
+ function injectIntoMetadata(metadataContent, manifestPath) {
6074
+ if (metadataContent.includes("manifest:") || metadataContent.includes("'manifest'")) {
6075
+ return metadataContent;
6076
+ }
6077
+ const closingBraceIndex = metadataContent.lastIndexOf("}");
6078
+ if (closingBraceIndex === -1) {
6079
+ return metadataContent;
6080
+ }
6081
+ const beforeBrace = metadataContent.substring(0, closingBraceIndex).trimEnd();
6082
+ const manifestLine = ` manifest: '${manifestPath}',`;
6083
+ if (!beforeBrace.endsWith("{")) {
6084
+ return `${beforeBrace}
6085
+ ${manifestLine}
6086
+ }`;
6087
+ }
6088
+ return `${beforeBrace}
6089
+ ${manifestLine}
6090
+ }`;
6091
+ }
6092
+ function createMetadataExport(manifestPath) {
6093
+ return `export const metadata: Metadata = {
6094
+ manifest: '${manifestPath}',
6095
+ };`;
6096
+ }
6097
+ function injectNextJsMetadata(filePath, content, options = {}) {
6098
+ const result = {
6099
+ injected: [],
6100
+ skipped: [],
6101
+ warnings: [],
6102
+ modified: false
6103
+ };
6104
+ if (!isNextJsLayoutFile(filePath)) {
6105
+ result.warnings.push(`File is not a Next.js layout file: ${filePath}`);
6106
+ return result;
6107
+ }
6108
+ if (!options.manifestPath) {
6109
+ result.warnings.push("No manifestPath provided");
6110
+ return result;
6111
+ }
6112
+ const finalManifestPath = buildManifestPath(
6113
+ options.manifestPath,
6114
+ options.basePath
6115
+ );
6116
+ let modifiedContent = content;
6117
+ if (!modifiedContent.includes("import type { Metadata }")) {
6118
+ const metadataTypeUsed = /:\s*Metadata\s*=|:\s*Metadata\s*[),;]/m.test(
6119
+ modifiedContent
6120
+ );
6121
+ if (metadataTypeUsed) {
6122
+ const importPattern = /^(import[^;]+;)/m;
6123
+ const importMatch = modifiedContent.match(importPattern);
6124
+ if (importMatch) {
6125
+ const metadataImport = "import type { Metadata } from 'next';\n";
6126
+ modifiedContent = metadataImport + modifiedContent;
6127
+ result.warnings.push("Added missing Metadata import");
6128
+ } else {
6129
+ const metadataImport = "import type { Metadata } from 'next';\n\n";
6130
+ modifiedContent = metadataImport + modifiedContent;
6131
+ result.warnings.push("Added missing Metadata import at the top");
6132
+ }
6133
+ }
6134
+ }
6135
+ const metadataExport = findMetadataExport(modifiedContent);
6136
+ if (metadataExport.found) {
6137
+ const updatedMetadata = injectIntoMetadata(
6138
+ metadataExport.content,
6139
+ finalManifestPath
6140
+ );
6141
+ if (updatedMetadata !== metadataExport.content) {
6142
+ modifiedContent = modifiedContent.substring(0, metadataExport.startIndex) + `export const metadata: Metadata = ${updatedMetadata}` + modifiedContent.substring(metadataExport.endIndex);
6143
+ result.injected.push(`manifest: '${finalManifestPath}'`);
6144
+ result.modified = true;
6145
+ return { ...result, content: modifiedContent };
6146
+ } else {
6147
+ result.skipped.push("manifest property already exists");
6148
+ return result;
6149
+ }
6150
+ } else {
6151
+ const layoutFunctionPattern = /export\s+default\s+function\s+RootLayout/;
6152
+ const functionMatch = modifiedContent.match(layoutFunctionPattern);
6153
+ if (functionMatch) {
6154
+ const insertIndex = functionMatch.index || 0;
6155
+ const metadataExport2 = createMetadataExport(finalManifestPath);
6156
+ modifiedContent = modifiedContent.substring(0, insertIndex) + metadataExport2 + "\n\n" + modifiedContent.substring(insertIndex);
6157
+ result.injected.push(
6158
+ `Created metadata export with manifest: '${finalManifestPath}'`
6159
+ );
6160
+ result.modified = true;
6161
+ return { ...result, content: modifiedContent };
6162
+ } else {
6163
+ result.warnings.push(
6164
+ "Could not find RootLayout function to insert metadata export"
6165
+ );
6166
+ return result;
6167
+ }
6168
+ }
6169
+ }
6170
+ function injectNextJsMetadataInFile(filePath, options = {}) {
6171
+ try {
6172
+ const content = (0, import_fs14.readFileSync)(filePath, "utf-8");
6173
+ const result = injectNextJsMetadata(filePath, content, options);
6174
+ if (result.modified && result.content) {
6175
+ (0, import_fs14.writeFileSync)(filePath, result.content, "utf-8");
6176
+ }
6177
+ return {
6178
+ injected: result.injected,
6179
+ skipped: result.skipped,
6180
+ warnings: result.warnings,
6181
+ modified: result.modified
6182
+ };
6183
+ } catch (error) {
6184
+ return {
6185
+ injected: [],
6186
+ skipped: [],
6187
+ warnings: [
6188
+ `Error processing file: ${error instanceof Error ? error.message : String(error)}`
6189
+ ],
6190
+ modified: false
6191
+ };
6192
+ }
6193
+ }
6194
+
6195
+ // src/validator/pwa-validator.ts
6196
+ var import_fs15 = require("fs");
5740
6197
  var import_path11 = require("path");
5741
6198
  var import_promises = require("fs/promises");
5742
6199
  function validateManifest(projectPath, outputDir) {
5743
6200
  const errors = [];
5744
6201
  const manifestPath = (0, import_path11.join)(outputDir, "manifest.json");
5745
- if (!(0, import_fs14.existsSync)(manifestPath)) {
6202
+ if (!(0, import_fs15.existsSync)(manifestPath)) {
5746
6203
  return {
5747
6204
  exists: false,
5748
6205
  valid: false,
@@ -5758,7 +6215,7 @@ function validateManifest(projectPath, outputDir) {
5758
6215
  };
5759
6216
  }
5760
6217
  try {
5761
- const manifestContent = (0, import_fs14.readFileSync)(manifestPath, "utf-8");
6218
+ const manifestContent = (0, import_fs15.readFileSync)(manifestPath, "utf-8");
5762
6219
  const manifest = JSON.parse(manifestContent);
5763
6220
  if (!manifest.name || manifest.name.trim().length === 0) {
5764
6221
  errors.push({
@@ -5872,7 +6329,7 @@ function validateIcons(projectPath, outputDir, manifest) {
5872
6329
  for (const icon of manifest.icons) {
5873
6330
  const iconPath = icon.src.startsWith("/") ? icon.src.substring(1) : icon.src;
5874
6331
  const fullIconPath = (0, import_path11.join)(outputDir, iconPath);
5875
- if (!(0, import_fs14.existsSync)(fullIconPath)) {
6332
+ if (!(0, import_fs15.existsSync)(fullIconPath)) {
5876
6333
  errors.push({
5877
6334
  code: "ICON_FILE_MISSING",
5878
6335
  message: `Icon file not found: ${iconPath}`,
@@ -5916,7 +6373,7 @@ function validateIcons(projectPath, outputDir, manifest) {
5916
6373
  function validateServiceWorker(projectPath, outputDir) {
5917
6374
  const errors = [];
5918
6375
  const swPath = (0, import_path11.join)(outputDir, "sw.js");
5919
- if (!(0, import_fs14.existsSync)(swPath)) {
6376
+ if (!(0, import_fs15.existsSync)(swPath)) {
5920
6377
  return {
5921
6378
  exists: false,
5922
6379
  valid: false,
@@ -5932,7 +6389,7 @@ function validateServiceWorker(projectPath, outputDir) {
5932
6389
  };
5933
6390
  }
5934
6391
  try {
5935
- const swContent = (0, import_fs14.readFileSync)(swPath, "utf-8");
6392
+ const swContent = (0, import_fs15.readFileSync)(swPath, "utf-8");
5936
6393
  if (!swContent.includes("workbox") && !swContent.includes("serviceWorker")) {
5937
6394
  errors.push({
5938
6395
  code: "SERVICE_WORKER_INVALID",
@@ -8822,6 +9279,9 @@ function resetBackendFactory() {
8822
9279
  injectMetaTags,
8823
9280
  injectMetaTagsInFile,
8824
9281
  injectMetaTagsInFilesBatch,
9282
+ injectNextJsMetadata,
9283
+ injectNextJsMetadataInFile,
9284
+ isNextJsLayoutFile,
8825
9285
  loadConfig,
8826
9286
  mapBackendManifestVarsToOptions,
8827
9287
  optimizeImage,