@vercel/microfrontends 2.1.3 → 2.2.1

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +4 -0
  3. package/dist/bin/cli.cjs +207 -90
  4. package/dist/config.d.ts +2 -2
  5. package/dist/experimental/sveltekit.cjs +180 -63
  6. package/dist/experimental/sveltekit.cjs.map +1 -1
  7. package/dist/experimental/sveltekit.d.ts +6 -0
  8. package/dist/experimental/sveltekit.js +180 -63
  9. package/dist/experimental/sveltekit.js.map +1 -1
  10. package/dist/experimental/vite.cjs +177 -66
  11. package/dist/experimental/vite.cjs.map +1 -1
  12. package/dist/experimental/vite.js +177 -66
  13. package/dist/experimental/vite.js.map +1 -1
  14. package/dist/microfrontends/server.cjs +173 -60
  15. package/dist/microfrontends/server.cjs.map +1 -1
  16. package/dist/microfrontends/server.d.ts +2 -2
  17. package/dist/microfrontends/server.js +173 -60
  18. package/dist/microfrontends/server.js.map +1 -1
  19. package/dist/microfrontends/utils.cjs +50 -7
  20. package/dist/microfrontends/utils.cjs.map +1 -1
  21. package/dist/microfrontends/utils.d.ts +1 -1
  22. package/dist/microfrontends/utils.js +50 -7
  23. package/dist/microfrontends/utils.js.map +1 -1
  24. package/dist/next/config.cjs +208 -113
  25. package/dist/next/config.cjs.map +1 -1
  26. package/dist/next/config.d.ts +11 -1
  27. package/dist/next/config.js +208 -113
  28. package/dist/next/config.js.map +1 -1
  29. package/dist/next/middleware.cjs +35 -17
  30. package/dist/next/middleware.cjs.map +1 -1
  31. package/dist/next/middleware.js +35 -17
  32. package/dist/next/middleware.js.map +1 -1
  33. package/dist/next/testing.d.ts +2 -2
  34. package/dist/overrides.d.ts +3 -3
  35. package/dist/schema.d.ts +2 -2
  36. package/dist/{types-88602303.d.ts → types-b9ea41b2.d.ts} +1 -1
  37. package/dist/{types-e7523e61.d.ts → types-dcd8b17a.d.ts} +71 -24
  38. package/dist/utils/mfe-port.cjs +173 -60
  39. package/dist/utils/mfe-port.cjs.map +1 -1
  40. package/dist/utils/mfe-port.js +173 -60
  41. package/dist/utils/mfe-port.js.map +1 -1
  42. package/dist/validation.cjs +47 -38
  43. package/dist/validation.cjs.map +1 -1
  44. package/dist/validation.d.ts +1 -1
  45. package/dist/validation.js +47 -38
  46. package/dist/validation.js.map +1 -1
  47. package/package.json +1 -1
  48. package/schema/schema.json +47 -38
@@ -222,10 +222,32 @@ var import_node_fs2 = require("fs");
222
222
  var import_jsonc_parser = require("jsonc-parser");
223
223
  var import_fast_glob = __toESM(require("fast-glob"), 1);
224
224
 
225
+ // src/bin/logger.ts
226
+ function debug(...args) {
227
+ if (process.env.MFE_DEBUG) {
228
+ console.log(...args);
229
+ }
230
+ }
231
+ function info(...args) {
232
+ console.log(...args);
233
+ }
234
+ function warn(...args) {
235
+ console.warn(...args);
236
+ }
237
+ function error(...args) {
238
+ console.error(...args);
239
+ }
240
+ var logger = {
241
+ debug,
242
+ info,
243
+ warn,
244
+ error
245
+ };
246
+
225
247
  // src/config/microfrontends/utils/get-config-file-name.ts
226
248
  var DEFAULT_CONFIGURATION_FILENAMES = [
227
- "microfrontends.jsonc",
228
- "microfrontends.json"
249
+ "microfrontends.json",
250
+ "microfrontends.jsonc"
229
251
  ];
230
252
  function getPossibleConfigurationFilenames({
231
253
  customConfigFilename
@@ -233,7 +255,7 @@ function getPossibleConfigurationFilenames({
233
255
  if (customConfigFilename) {
234
256
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
235
257
  throw new Error(
236
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
258
+ `Found VC_MICROFRONTENDS_CONFIG_FILE_NAME but the name is invalid. Received: ${customConfigFilename}. The file name must end with '.json' or '.jsonc'. It's also possible for the env var to include the path, eg microfrontends-dev.json or /path/to/microfrontends-dev.json.`
237
259
  );
238
260
  }
239
261
  return Array.from(
@@ -251,6 +273,10 @@ function findPackageWithMicrofrontendsConfig({
251
273
  customConfigFilename
252
274
  }) {
253
275
  const applicationName = applicationContext.name;
276
+ logger.debug(
277
+ "[MFE Config] Searching repository for configs containing application:",
278
+ applicationName
279
+ );
254
280
  try {
255
281
  const microfrontendsJsonPaths = import_fast_glob.default.globSync(
256
282
  `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
@@ -262,6 +288,11 @@ function findPackageWithMicrofrontendsConfig({
262
288
  ignore: ["**/node_modules/**", "**/.git/**"]
263
289
  }
264
290
  );
291
+ logger.debug(
292
+ "[MFE Config] Found",
293
+ microfrontendsJsonPaths.length,
294
+ "config file(s) in repository"
295
+ );
265
296
  const matchingPaths = [];
266
297
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
267
298
  try {
@@ -271,19 +302,31 @@ function findPackageWithMicrofrontendsConfig({
271
302
  );
272
303
  const microfrontendsJson = (0, import_jsonc_parser.parse)(microfrontendsJsonContent);
273
304
  if (microfrontendsJson.applications[applicationName]) {
305
+ logger.debug(
306
+ "[MFE Config] Found application in config:",
307
+ microfrontendsJsonPath
308
+ );
274
309
  matchingPaths.push(microfrontendsJsonPath);
275
310
  } else {
276
311
  for (const [_, app] of Object.entries(
277
312
  microfrontendsJson.applications
278
313
  )) {
279
314
  if (app.packageName === applicationName) {
315
+ logger.debug(
316
+ "[MFE Config] Found application via packageName in config:",
317
+ microfrontendsJsonPath
318
+ );
280
319
  matchingPaths.push(microfrontendsJsonPath);
281
320
  }
282
321
  }
283
322
  }
284
- } catch (error) {
323
+ } catch (error2) {
285
324
  }
286
325
  }
326
+ logger.debug(
327
+ "[MFE Config] Total matching config files:",
328
+ matchingPaths.length
329
+ );
287
330
  if (matchingPaths.length > 1) {
288
331
  throw new MicrofrontendError(
289
332
  `Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
@@ -317,9 +360,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
317
360
  }
318
361
  const [packageJsonPath] = matchingPaths;
319
362
  return (0, import_node_path2.dirname)(packageJsonPath);
320
- } catch (error) {
321
- if (error instanceof MicrofrontendError) {
322
- throw error;
363
+ } catch (error2) {
364
+ if (error2 instanceof MicrofrontendError) {
365
+ throw error2;
323
366
  }
324
367
  return null;
325
368
  }
@@ -364,8 +407,8 @@ function isMonorepo({
364
407
  import_node_fs3.default.readFileSync(packageJsonPath, "utf-8")
365
408
  );
366
409
  return packageJson.workspaces !== void 0;
367
- } catch (error) {
368
- console.error("Error determining if repository is a monorepo", error);
410
+ } catch (error2) {
411
+ logger.error("Error determining if repository is a monorepo", error2);
369
412
  return false;
370
413
  }
371
414
  }
@@ -1082,15 +1125,18 @@ var import_node_fs6 = __toESM(require("fs"), 1);
1082
1125
  var import_node_path6 = __toESM(require("path"), 1);
1083
1126
  function getApplicationContext(opts) {
1084
1127
  if (opts?.appName) {
1128
+ logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
1085
1129
  return { name: opts.appName };
1086
1130
  }
1087
1131
  if (process.env.VERCEL_PROJECT_NAME) {
1132
+ logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
1088
1133
  return {
1089
1134
  name: process.env.VERCEL_PROJECT_NAME,
1090
1135
  projectName: process.env.VERCEL_PROJECT_NAME
1091
1136
  };
1092
1137
  }
1093
1138
  if (process.env.NX_TASK_TARGET_PROJECT) {
1139
+ logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
1094
1140
  return {
1095
1141
  name: process.env.NX_TASK_TARGET_PROJECT,
1096
1142
  packageJsonName: process.env.NX_TASK_TARGET_PROJECT
@@ -1103,6 +1149,7 @@ function getApplicationContext(opts) {
1103
1149
  );
1104
1150
  const projectJson = JSON.parse(vercelProjectJsonPath);
1105
1151
  if (projectJson.projectName) {
1152
+ logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
1106
1153
  return {
1107
1154
  name: projectJson.projectName,
1108
1155
  projectName: projectJson.projectName
@@ -1126,6 +1173,7 @@ function getApplicationContext(opts) {
1126
1173
  }
1127
1174
  );
1128
1175
  }
1176
+ logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
1129
1177
  return { name: packageJson.name, packageJsonName: packageJson.name };
1130
1178
  } catch (err) {
1131
1179
  throw MicrofrontendError.handle(err, {
@@ -1159,38 +1207,28 @@ var schema_default = {
1159
1207
  type: "object",
1160
1208
  properties: {
1161
1209
  $schema: {
1162
- type: "string"
1210
+ type: "string",
1211
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1163
1212
  },
1164
1213
  version: {
1165
1214
  type: "string",
1166
- const: "1"
1167
- },
1168
- options: {
1169
- $ref: "#/definitions/Options"
1215
+ const: "1",
1216
+ description: "The version of the microfrontends config schema."
1170
1217
  },
1171
1218
  applications: {
1172
1219
  $ref: "#/definitions/ApplicationRouting",
1173
- description: "Mapping of application names to the routes that they host. Only needs to be defined in the application that owns the primary microfrontend domain"
1220
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1221
+ },
1222
+ options: {
1223
+ $ref: "#/definitions/Options",
1224
+ description: "Optional configuration options for the microfrontend."
1174
1225
  }
1175
1226
  },
1176
1227
  required: [
1177
1228
  "applications"
1178
1229
  ],
1179
- additionalProperties: false
1180
- },
1181
- Options: {
1182
- type: "object",
1183
- properties: {
1184
- disableOverrides: {
1185
- type: "boolean",
1186
- description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect."
1187
- },
1188
- localProxyPort: {
1189
- type: "number",
1190
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1191
- }
1192
- },
1193
- additionalProperties: false
1230
+ additionalProperties: false,
1231
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1194
1232
  },
1195
1233
  ApplicationRouting: {
1196
1234
  type: "object",
@@ -1198,8 +1236,9 @@ var schema_default = {
1198
1236
  $ref: "#/definitions/Application"
1199
1237
  },
1200
1238
  propertyNames: {
1201
- description: "The unique identifier for a Microfrontend Application.\n\nMust match the Vercel project name.\n\nNote: If this name does not also match the name used to run the application, (e.g. the `name` from the `package.json`), then the `packageName` field should be set."
1202
- }
1239
+ description: "The Vercel project name of the microfrontend application.\n\nNote: If this name does not also match the name `name` from the `package.json`, set `packageName` with the name used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
1240
+ },
1241
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1203
1242
  },
1204
1243
  Application: {
1205
1244
  anyOf: [
@@ -1209,14 +1248,15 @@ var schema_default = {
1209
1248
  {
1210
1249
  $ref: "#/definitions/ChildApplication"
1211
1250
  }
1212
- ]
1251
+ ],
1252
+ description: "The configuration for a microfrontend application. There must always be one default application."
1213
1253
  },
1214
1254
  DefaultApplication: {
1215
1255
  type: "object",
1216
1256
  properties: {
1217
1257
  packageName: {
1218
1258
  type: "string",
1219
- description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`."
1259
+ description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
1220
1260
  },
1221
1261
  development: {
1222
1262
  $ref: "#/definitions/DefaultDevelopment",
@@ -1236,15 +1276,15 @@ var schema_default = {
1236
1276
  "number",
1237
1277
  "string"
1238
1278
  ],
1239
- description: "A local port number or host string that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTP. If omitted, the port defaults to a unique, but stable (based on the application name) number.\n\nExamples of valid values:\n- 8080\n- my.localhost.me\n- my.localhost.me:8080\n- https://my.localhost.me\n- https://my.localhost.me:8080"
1279
+ description: "A local port number or host that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional).\n\nExamples of valid values: 8080, my.localhost.me, my.localhost.me:8080, https://my.localhost.me, https://my.localhost.me:8080.\n\nThe default value is http://localhost:<port> where port is a stable, unique port number (based on the application name).\n\nSee https://vercel.com/docs/microfrontends/local-development."
1240
1280
  },
1241
1281
  task: {
1242
1282
  type: "string",
1243
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1283
+ description: 'The task to run when starting the development server. Should reference a script in the package.json of the application.\n\nThe default value is "dev".\n\nSee https://vercel.com/docs/microfrontends/local-development.'
1244
1284
  },
1245
1285
  fallback: {
1246
1286
  type: "string",
1247
- description: "Fallback for local development, could point to any environment. This is required for the default app. This value is used as the fallback for child apps as well if they do not have a fallback.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS."
1287
+ description: "Fallback for local development, could point to any environment. This is required for the default app. This value is used as the fallback for child apps as well if they do not have a fallback.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS.\n\nSee https://vercel.com/docs/microfrontends/local-development."
1248
1288
  }
1249
1289
  },
1250
1290
  required: [
@@ -1257,7 +1297,7 @@ var schema_default = {
1257
1297
  properties: {
1258
1298
  packageName: {
1259
1299
  type: "string",
1260
- description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`."
1300
+ description: "The name used to run the application, e.g. the `name` field in the `package.json`.\n\nThis is used by the local proxy to map the application config to the locally running app.\n\nThis is only necessary when the application name does not match the `name` used in `package.json`.\n\nSee https://vercel.com/docs/microfrontends/configuration#application-naming."
1261
1301
  },
1262
1302
  development: {
1263
1303
  $ref: "#/definitions/ChildDevelopment",
@@ -1265,11 +1305,11 @@ var schema_default = {
1265
1305
  },
1266
1306
  routing: {
1267
1307
  $ref: "#/definitions/Routing",
1268
- description: "Groups of path expressions that are routed to this application."
1308
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1269
1309
  },
1270
1310
  assetPrefix: {
1271
1311
  type: "string",
1272
- description: "The name of the asset prefix to use instead of the auto-generated name.\n\nThe asset prefix is used to prefix all paths to static assets, such as JS, CSS, or images that are served by a specific application. It is necessary to ensure there are no conflicts with other applications on the same domain.\n\nAn auto-generated asset prefix of the form `vc-ap-<hash>` is used when this field is not provided.\n\nWhen this field is provided, `/${assetPrefix}/:path*` must also be added to the list of paths in the `routing` field. Changing the asset prefix after a microfrontend application has already been deployed is not a forwards and backwards compatible change, and the asset prefix should be added to the `routing` field and deployed before setting the `assetPrefix` field."
1312
+ description: "The name of the asset prefix to use instead of the auto-generated name.\n\nThe asset prefix is used to prefix all paths to static assets, such as JS, CSS, or images that are served by a specific application. It is necessary to ensure there are no conflicts with other applications on the same domain.\n\nAn auto-generated asset prefix of the form `vc-ap-<hash>` is used when this field is not provided.\n\nWhen this field is provided, `/${assetPrefix}/:path*` must also be added to the list of paths in the `routing` field. Changing the asset prefix after a microfrontend application has already been deployed is not a forwards and backwards compatible change, and the asset prefix should be added to the `routing` field and deployed before setting the `assetPrefix` field.\n\nThe default value is the auto-generated asset prefix of the form `vc-ap-<hash>`.\n\nSee https://vercel.com/docs/microfrontends/path-routing#asset-prefix."
1273
1313
  }
1274
1314
  },
1275
1315
  required: [
@@ -1285,15 +1325,15 @@ var schema_default = {
1285
1325
  "number",
1286
1326
  "string"
1287
1327
  ],
1288
- description: "A local port number or host string that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTP. If omitted, the port defaults to a unique, but stable (based on the application name) number.\n\nExamples of valid values:\n- 8080\n- my.localhost.me\n- my.localhost.me:8080\n- https://my.localhost.me\n- https://my.localhost.me:8080"
1328
+ description: "A local port number or host that this application runs on when it is running locally. If passing a string, include the protocol (optional), host (required) and port (optional).\n\nExamples of valid values: 8080, my.localhost.me, my.localhost.me:8080, https://my.localhost.me, https://my.localhost.me:8080.\n\nThe default value is http://localhost:<port> where port is a stable, unique port number (based on the application name).\n\nSee https://vercel.com/docs/microfrontends/local-development."
1289
1329
  },
1290
1330
  task: {
1291
1331
  type: "string",
1292
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1332
+ description: 'The task to run when starting the development server. Should reference a script in the package.json of the application.\n\nThe default value is "dev".\n\nSee https://vercel.com/docs/microfrontends/local-development.'
1293
1333
  },
1294
1334
  fallback: {
1295
1335
  type: "string",
1296
- description: "Fallback for local development, could point to any environment. This is optional for child apps. If not provided, the fallback of the default app will be used.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS."
1336
+ description: "Fallback for local development, could point to any environment. If not provided for child apps, the fallback of the default app will be used.\n\nIf passing a string, include the protocol (optional), host (required) and port (optional). For example: `https://this.ismyhost:8080`. If omitted, the protocol defaults to HTTPS. If omitted, the port defaults to `80` for HTTP and `443` for HTTPS.\n\nSee https://vercel.com/docs/microfrontends/local-development."
1297
1337
  }
1298
1338
  },
1299
1339
  additionalProperties: false
@@ -1302,29 +1342,46 @@ var schema_default = {
1302
1342
  type: "array",
1303
1343
  items: {
1304
1344
  $ref: "#/definitions/PathGroup"
1305
- }
1345
+ },
1346
+ description: "A list of path groups that are routed to this application."
1306
1347
  },
1307
1348
  PathGroup: {
1308
1349
  type: "object",
1309
1350
  properties: {
1310
1351
  group: {
1311
1352
  type: "string",
1312
- description: "Optional group name for the paths"
1353
+ description: "Group name for the paths."
1313
1354
  },
1314
1355
  flag: {
1315
1356
  type: "string",
1316
- description: "flag name that can be used to enable/disable all paths in the group"
1357
+ description: "The name of the feature flag that controls routing for this group of paths. See https://vercel.com/docs/microfrontends/path-routing#routing-changes-safely-with-flags."
1317
1358
  },
1318
1359
  paths: {
1319
1360
  type: "array",
1320
1361
  items: {
1321
1362
  type: "string"
1322
- }
1363
+ },
1364
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1323
1365
  }
1324
1366
  },
1325
1367
  required: [
1326
1368
  "paths"
1327
1369
  ],
1370
+ additionalProperties: false,
1371
+ description: "A group of paths that is routed to this application."
1372
+ },
1373
+ Options: {
1374
+ type: "object",
1375
+ properties: {
1376
+ disableOverrides: {
1377
+ type: "boolean",
1378
+ description: "If you want to disable the overrides for the site. For example, if you are managing rewrites between applications externally, you may wish to disable the overrides on the toolbar as they will have no effect.\n\nSee https://vercel.com/docs/microfrontends/managing-microfrontends/vercel-toolbar#routing-overrides."
1379
+ },
1380
+ localProxyPort: {
1381
+ type: "number",
1382
+ description: "The port number used by the local proxy server.\n\nThe default value is 3024.\n\nSee https://vercel.com/docs/microfrontends/local-development."
1383
+ }
1384
+ },
1328
1385
  additionalProperties: false
1329
1386
  }
1330
1387
  }
@@ -1343,19 +1400,19 @@ function formatAjvErrors(errors) {
1343
1400
  return [];
1344
1401
  }
1345
1402
  const errorMessages = [];
1346
- for (const error of errors) {
1347
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1403
+ for (const error2 of errors) {
1404
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1348
1405
  continue;
1349
1406
  }
1350
- const instancePath = error.instancePath.slice(1);
1407
+ const instancePath = error2.instancePath.slice(1);
1351
1408
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1352
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1409
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1353
1410
  errorMessages.push(
1354
1411
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1355
1412
  );
1356
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1413
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1357
1414
  const anyOfErrors = errors.filter(
1358
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1415
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1359
1416
  );
1360
1417
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1361
1418
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1371,13 +1428,13 @@ function formatAjvErrors(errors) {
1371
1428
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1372
1429
  );
1373
1430
  }
1374
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1431
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1375
1432
  errorMessages.push(
1376
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1433
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1377
1434
  );
1378
- } else if (error.keyword === "required") {
1435
+ } else if (error2.keyword === "required") {
1379
1436
  errorMessages.push(
1380
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1437
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1381
1438
  );
1382
1439
  }
1383
1440
  }
@@ -1390,8 +1447,8 @@ function validateSchema(configString) {
1390
1447
  const isValid = validate(parsedConfig);
1391
1448
  if (!isValid) {
1392
1449
  throw new MicrofrontendError(
1393
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1394
- - ${error}`).join(
1450
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1451
+ - ${error2}`).join(
1395
1452
  ""
1396
1453
  )}
1397
1454
 
@@ -1488,7 +1545,13 @@ var MicrofrontendsServer = class {
1488
1545
  filePath,
1489
1546
  cookies
1490
1547
  } = {}) {
1548
+ logger.debug("[MFE Config] Starting config inference", {
1549
+ appName,
1550
+ directory: directory || process.cwd(),
1551
+ filePath
1552
+ });
1491
1553
  if (filePath) {
1554
+ logger.debug("[MFE Config] Using explicit filePath:", filePath);
1492
1555
  return MicrofrontendsServer.fromFile({
1493
1556
  filePath,
1494
1557
  cookies
@@ -1496,16 +1559,25 @@ var MicrofrontendsServer = class {
1496
1559
  }
1497
1560
  try {
1498
1561
  const packageRoot = findPackageRoot(directory);
1562
+ logger.debug("[MFE Config] Package root:", packageRoot);
1499
1563
  const applicationContext = getApplicationContext({
1500
1564
  appName,
1501
1565
  packageRoot
1502
1566
  });
1567
+ logger.debug("[MFE Config] Application context:", applicationContext);
1503
1568
  const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1569
+ if (customConfigFilename) {
1570
+ logger.debug(
1571
+ "[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
1572
+ customConfigFilename
1573
+ );
1574
+ }
1504
1575
  const maybeConfig = findConfig({
1505
1576
  dir: packageRoot,
1506
1577
  customConfigFilename
1507
1578
  });
1508
1579
  if (maybeConfig) {
1580
+ logger.debug("[MFE Config] Config found at package root:", maybeConfig);
1509
1581
  return MicrofrontendsServer.fromFile({
1510
1582
  filePath: maybeConfig,
1511
1583
  cookies
@@ -1513,42 +1585,78 @@ var MicrofrontendsServer = class {
1513
1585
  }
1514
1586
  const repositoryRoot = findRepositoryRoot();
1515
1587
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1588
+ logger.debug(
1589
+ "[MFE Config] Repository root:",
1590
+ repositoryRoot,
1591
+ "Is monorepo:",
1592
+ isMonorepo2
1593
+ );
1516
1594
  const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1517
1595
  if (typeof configFromEnv === "string") {
1596
+ logger.debug(
1597
+ "[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
1598
+ configFromEnv
1599
+ );
1518
1600
  const maybeConfigFromEnv = (0, import_node_path8.resolve)(packageRoot, configFromEnv);
1519
1601
  if (maybeConfigFromEnv) {
1602
+ logger.debug(
1603
+ "[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
1604
+ maybeConfigFromEnv
1605
+ );
1520
1606
  return MicrofrontendsServer.fromFile({
1521
1607
  filePath: maybeConfigFromEnv,
1522
1608
  cookies
1523
1609
  });
1524
1610
  }
1525
1611
  } else {
1612
+ const vercelDir = (0, import_node_path8.join)(packageRoot, ".vercel");
1613
+ logger.debug(
1614
+ "[MFE Config] Searching for config in .vercel directory:",
1615
+ vercelDir
1616
+ );
1526
1617
  const maybeConfigFromVercel = findConfig({
1527
- dir: (0, import_node_path8.join)(packageRoot, ".vercel"),
1618
+ dir: vercelDir,
1528
1619
  customConfigFilename
1529
1620
  });
1530
1621
  if (maybeConfigFromVercel) {
1622
+ logger.debug(
1623
+ "[MFE Config] Config found in .vercel directory:",
1624
+ maybeConfigFromVercel
1625
+ );
1531
1626
  return MicrofrontendsServer.fromFile({
1532
1627
  filePath: maybeConfigFromVercel,
1533
1628
  cookies
1534
1629
  });
1535
1630
  }
1536
1631
  if (isMonorepo2) {
1632
+ logger.debug(
1633
+ "[MFE Config] Inferring microfrontends location in monorepo for application:",
1634
+ applicationContext.name
1635
+ );
1537
1636
  const defaultPackage = inferMicrofrontendsLocation({
1538
1637
  repositoryRoot,
1539
1638
  applicationContext,
1540
1639
  customConfigFilename
1541
1640
  });
1641
+ logger.debug(
1642
+ "[MFE Config] Inferred package location:",
1643
+ defaultPackage
1644
+ );
1542
1645
  const maybeConfigFromDefault = findConfig({
1543
1646
  dir: defaultPackage,
1544
1647
  customConfigFilename
1545
1648
  });
1546
1649
  if (maybeConfigFromDefault) {
1650
+ logger.debug(
1651
+ "[MFE Config] Config found in inferred package:",
1652
+ maybeConfigFromDefault
1653
+ );
1547
1654
  return MicrofrontendsServer.fromFile({
1548
1655
  filePath: maybeConfigFromDefault,
1549
1656
  cookies
1550
1657
  });
1551
1658
  }
1659
+ logger.debug("[MFE Config] No config found in inferred package");
1552
1660
  }
1553
1661
  }
1554
1662
  throw new MicrofrontendError(
@@ -1574,8 +1682,13 @@ var MicrofrontendsServer = class {
1574
1682
  cookies
1575
1683
  }) {
1576
1684
  try {
1685
+ logger.debug("[MFE Config] Reading config from file:", filePath);
1577
1686
  const configJson = import_node_fs7.default.readFileSync(filePath, "utf-8");
1578
1687
  const config = MicrofrontendsServer.validate(configJson);
1688
+ logger.debug(
1689
+ "[MFE Config] Config loaded with applications:",
1690
+ Object.keys(config.applications)
1691
+ );
1579
1692
  return new MicrofrontendsServer({
1580
1693
  config,
1581
1694
  overrides: cookies ? parseOverrides(cookies) : void 0