@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
@@ -1,9 +1,35 @@
1
+ // src/bin/local-proxy-is-running.ts
2
+ function localProxyIsRunning() {
3
+ return process.env.TURBO_TASK_HAS_MFE_PROXY === "true";
4
+ }
5
+
6
+ // src/bin/logger.ts
7
+ function debug(...args) {
8
+ if (process.env.MFE_DEBUG) {
9
+ console.log(...args);
10
+ }
11
+ }
12
+ function info(...args) {
13
+ console.log(...args);
14
+ }
15
+ function warn(...args) {
16
+ console.warn(...args);
17
+ }
18
+ function error(...args) {
19
+ console.error(...args);
20
+ }
21
+ var logger = {
22
+ debug,
23
+ info,
24
+ warn,
25
+ error
26
+ };
27
+
1
28
  // src/bin/check-proxy.ts
2
29
  function displayLocalProxyInfo(port) {
3
- const { MFE_PROXY_MESSAGE_PRINTED, TURBO_TASK_HAS_MFE_PROXY } = process.env;
4
- if (TURBO_TASK_HAS_MFE_PROXY === "true" && MFE_PROXY_MESSAGE_PRINTED !== "true") {
30
+ if (localProxyIsRunning() && process.env.MFE_PROXY_MESSAGE_PRINTED !== "true") {
5
31
  process.env.MFE_PROXY_MESSAGE_PRINTED = "true";
6
- console.log(`Microfrontends Proxy running on http://localhost:${port}`);
32
+ logger.info(`Microfrontends Proxy running on http://localhost:${port}`);
7
33
  }
8
34
  }
9
35
 
@@ -198,8 +224,8 @@ import fg from "fast-glob";
198
224
 
199
225
  // src/config/microfrontends/utils/get-config-file-name.ts
200
226
  var DEFAULT_CONFIGURATION_FILENAMES = [
201
- "microfrontends.jsonc",
202
- "microfrontends.json"
227
+ "microfrontends.json",
228
+ "microfrontends.jsonc"
203
229
  ];
204
230
  function getPossibleConfigurationFilenames({
205
231
  customConfigFilename
@@ -207,7 +233,7 @@ function getPossibleConfigurationFilenames({
207
233
  if (customConfigFilename) {
208
234
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
209
235
  throw new Error(
210
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
236
+ `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.`
211
237
  );
212
238
  }
213
239
  return Array.from(
@@ -225,6 +251,10 @@ function findPackageWithMicrofrontendsConfig({
225
251
  customConfigFilename
226
252
  }) {
227
253
  const applicationName = applicationContext.name;
254
+ logger.debug(
255
+ "[MFE Config] Searching repository for configs containing application:",
256
+ applicationName
257
+ );
228
258
  try {
229
259
  const microfrontendsJsonPaths = fg.globSync(
230
260
  `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
@@ -236,6 +266,11 @@ function findPackageWithMicrofrontendsConfig({
236
266
  ignore: ["**/node_modules/**", "**/.git/**"]
237
267
  }
238
268
  );
269
+ logger.debug(
270
+ "[MFE Config] Found",
271
+ microfrontendsJsonPaths.length,
272
+ "config file(s) in repository"
273
+ );
239
274
  const matchingPaths = [];
240
275
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
241
276
  try {
@@ -245,19 +280,31 @@ function findPackageWithMicrofrontendsConfig({
245
280
  );
246
281
  const microfrontendsJson = parse(microfrontendsJsonContent);
247
282
  if (microfrontendsJson.applications[applicationName]) {
283
+ logger.debug(
284
+ "[MFE Config] Found application in config:",
285
+ microfrontendsJsonPath
286
+ );
248
287
  matchingPaths.push(microfrontendsJsonPath);
249
288
  } else {
250
289
  for (const [_, app] of Object.entries(
251
290
  microfrontendsJson.applications
252
291
  )) {
253
292
  if (app.packageName === applicationName) {
293
+ logger.debug(
294
+ "[MFE Config] Found application via packageName in config:",
295
+ microfrontendsJsonPath
296
+ );
254
297
  matchingPaths.push(microfrontendsJsonPath);
255
298
  }
256
299
  }
257
300
  }
258
- } catch (error) {
301
+ } catch (error2) {
259
302
  }
260
303
  }
304
+ logger.debug(
305
+ "[MFE Config] Total matching config files:",
306
+ matchingPaths.length
307
+ );
261
308
  if (matchingPaths.length > 1) {
262
309
  throw new MicrofrontendError(
263
310
  `Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
@@ -291,9 +338,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
291
338
  }
292
339
  const [packageJsonPath] = matchingPaths;
293
340
  return dirname(packageJsonPath);
294
- } catch (error) {
295
- if (error instanceof MicrofrontendError) {
296
- throw error;
341
+ } catch (error2) {
342
+ if (error2 instanceof MicrofrontendError) {
343
+ throw error2;
297
344
  }
298
345
  return null;
299
346
  }
@@ -338,8 +385,8 @@ function isMonorepo({
338
385
  fs2.readFileSync(packageJsonPath, "utf-8")
339
386
  );
340
387
  return packageJson.workspaces !== void 0;
341
- } catch (error) {
342
- console.error("Error determining if repository is a monorepo", error);
388
+ } catch (error2) {
389
+ logger.error("Error determining if repository is a monorepo", error2);
343
390
  return false;
344
391
  }
345
392
  }
@@ -1056,15 +1103,18 @@ import fs5 from "node:fs";
1056
1103
  import path4 from "node:path";
1057
1104
  function getApplicationContext(opts) {
1058
1105
  if (opts?.appName) {
1106
+ logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
1059
1107
  return { name: opts.appName };
1060
1108
  }
1061
1109
  if (process.env.VERCEL_PROJECT_NAME) {
1110
+ logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
1062
1111
  return {
1063
1112
  name: process.env.VERCEL_PROJECT_NAME,
1064
1113
  projectName: process.env.VERCEL_PROJECT_NAME
1065
1114
  };
1066
1115
  }
1067
1116
  if (process.env.NX_TASK_TARGET_PROJECT) {
1117
+ logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
1068
1118
  return {
1069
1119
  name: process.env.NX_TASK_TARGET_PROJECT,
1070
1120
  packageJsonName: process.env.NX_TASK_TARGET_PROJECT
@@ -1077,6 +1127,7 @@ function getApplicationContext(opts) {
1077
1127
  );
1078
1128
  const projectJson = JSON.parse(vercelProjectJsonPath);
1079
1129
  if (projectJson.projectName) {
1130
+ logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
1080
1131
  return {
1081
1132
  name: projectJson.projectName,
1082
1133
  projectName: projectJson.projectName
@@ -1100,6 +1151,7 @@ function getApplicationContext(opts) {
1100
1151
  }
1101
1152
  );
1102
1153
  }
1154
+ logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
1103
1155
  return { name: packageJson.name, packageJsonName: packageJson.name };
1104
1156
  } catch (err) {
1105
1157
  throw MicrofrontendError.handle(err, {
@@ -1133,38 +1185,28 @@ var schema_default = {
1133
1185
  type: "object",
1134
1186
  properties: {
1135
1187
  $schema: {
1136
- type: "string"
1188
+ type: "string",
1189
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1137
1190
  },
1138
1191
  version: {
1139
1192
  type: "string",
1140
- const: "1"
1141
- },
1142
- options: {
1143
- $ref: "#/definitions/Options"
1193
+ const: "1",
1194
+ description: "The version of the microfrontends config schema."
1144
1195
  },
1145
1196
  applications: {
1146
1197
  $ref: "#/definitions/ApplicationRouting",
1147
- 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"
1198
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1199
+ },
1200
+ options: {
1201
+ $ref: "#/definitions/Options",
1202
+ description: "Optional configuration options for the microfrontend."
1148
1203
  }
1149
1204
  },
1150
1205
  required: [
1151
1206
  "applications"
1152
1207
  ],
1153
- additionalProperties: false
1154
- },
1155
- Options: {
1156
- type: "object",
1157
- properties: {
1158
- disableOverrides: {
1159
- type: "boolean",
1160
- 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."
1161
- },
1162
- localProxyPort: {
1163
- type: "number",
1164
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1165
- }
1166
- },
1167
- additionalProperties: false
1208
+ additionalProperties: false,
1209
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1168
1210
  },
1169
1211
  ApplicationRouting: {
1170
1212
  type: "object",
@@ -1172,8 +1214,9 @@ var schema_default = {
1172
1214
  $ref: "#/definitions/Application"
1173
1215
  },
1174
1216
  propertyNames: {
1175
- 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."
1176
- }
1217
+ 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."
1218
+ },
1219
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1177
1220
  },
1178
1221
  Application: {
1179
1222
  anyOf: [
@@ -1183,14 +1226,15 @@ var schema_default = {
1183
1226
  {
1184
1227
  $ref: "#/definitions/ChildApplication"
1185
1228
  }
1186
- ]
1229
+ ],
1230
+ description: "The configuration for a microfrontend application. There must always be one default application."
1187
1231
  },
1188
1232
  DefaultApplication: {
1189
1233
  type: "object",
1190
1234
  properties: {
1191
1235
  packageName: {
1192
1236
  type: "string",
1193
- 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`."
1237
+ 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."
1194
1238
  },
1195
1239
  development: {
1196
1240
  $ref: "#/definitions/DefaultDevelopment",
@@ -1210,15 +1254,15 @@ var schema_default = {
1210
1254
  "number",
1211
1255
  "string"
1212
1256
  ],
1213
- 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"
1257
+ 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."
1214
1258
  },
1215
1259
  task: {
1216
1260
  type: "string",
1217
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1261
+ 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.'
1218
1262
  },
1219
1263
  fallback: {
1220
1264
  type: "string",
1221
- 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."
1265
+ 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."
1222
1266
  }
1223
1267
  },
1224
1268
  required: [
@@ -1231,7 +1275,7 @@ var schema_default = {
1231
1275
  properties: {
1232
1276
  packageName: {
1233
1277
  type: "string",
1234
- 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`."
1278
+ 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."
1235
1279
  },
1236
1280
  development: {
1237
1281
  $ref: "#/definitions/ChildDevelopment",
@@ -1239,11 +1283,11 @@ var schema_default = {
1239
1283
  },
1240
1284
  routing: {
1241
1285
  $ref: "#/definitions/Routing",
1242
- description: "Groups of path expressions that are routed to this application."
1286
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1243
1287
  },
1244
1288
  assetPrefix: {
1245
1289
  type: "string",
1246
- 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."
1290
+ 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."
1247
1291
  }
1248
1292
  },
1249
1293
  required: [
@@ -1259,15 +1303,15 @@ var schema_default = {
1259
1303
  "number",
1260
1304
  "string"
1261
1305
  ],
1262
- 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"
1306
+ 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."
1263
1307
  },
1264
1308
  task: {
1265
1309
  type: "string",
1266
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1310
+ 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.'
1267
1311
  },
1268
1312
  fallback: {
1269
1313
  type: "string",
1270
- 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."
1314
+ 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."
1271
1315
  }
1272
1316
  },
1273
1317
  additionalProperties: false
@@ -1276,29 +1320,46 @@ var schema_default = {
1276
1320
  type: "array",
1277
1321
  items: {
1278
1322
  $ref: "#/definitions/PathGroup"
1279
- }
1323
+ },
1324
+ description: "A list of path groups that are routed to this application."
1280
1325
  },
1281
1326
  PathGroup: {
1282
1327
  type: "object",
1283
1328
  properties: {
1284
1329
  group: {
1285
1330
  type: "string",
1286
- description: "Optional group name for the paths"
1331
+ description: "Group name for the paths."
1287
1332
  },
1288
1333
  flag: {
1289
1334
  type: "string",
1290
- description: "flag name that can be used to enable/disable all paths in the group"
1335
+ 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."
1291
1336
  },
1292
1337
  paths: {
1293
1338
  type: "array",
1294
1339
  items: {
1295
1340
  type: "string"
1296
- }
1341
+ },
1342
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1297
1343
  }
1298
1344
  },
1299
1345
  required: [
1300
1346
  "paths"
1301
1347
  ],
1348
+ additionalProperties: false,
1349
+ description: "A group of paths that is routed to this application."
1350
+ },
1351
+ Options: {
1352
+ type: "object",
1353
+ properties: {
1354
+ disableOverrides: {
1355
+ type: "boolean",
1356
+ 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."
1357
+ },
1358
+ localProxyPort: {
1359
+ type: "number",
1360
+ 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."
1361
+ }
1362
+ },
1302
1363
  additionalProperties: false
1303
1364
  }
1304
1365
  }
@@ -1317,19 +1378,19 @@ function formatAjvErrors(errors) {
1317
1378
  return [];
1318
1379
  }
1319
1380
  const errorMessages = [];
1320
- for (const error of errors) {
1321
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1381
+ for (const error2 of errors) {
1382
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1322
1383
  continue;
1323
1384
  }
1324
- const instancePath = error.instancePath.slice(1);
1385
+ const instancePath = error2.instancePath.slice(1);
1325
1386
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1326
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1387
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1327
1388
  errorMessages.push(
1328
1389
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1329
1390
  );
1330
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1391
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1331
1392
  const anyOfErrors = errors.filter(
1332
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1393
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1333
1394
  );
1334
1395
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1335
1396
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1345,13 +1406,13 @@ function formatAjvErrors(errors) {
1345
1406
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1346
1407
  );
1347
1408
  }
1348
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1409
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1349
1410
  errorMessages.push(
1350
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1411
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1351
1412
  );
1352
- } else if (error.keyword === "required") {
1413
+ } else if (error2.keyword === "required") {
1353
1414
  errorMessages.push(
1354
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1415
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1355
1416
  );
1356
1417
  }
1357
1418
  }
@@ -1364,8 +1425,8 @@ function validateSchema(configString) {
1364
1425
  const isValid = validate(parsedConfig);
1365
1426
  if (!isValid) {
1366
1427
  throw new MicrofrontendError(
1367
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1368
- - ${error}`).join(
1428
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1429
+ - ${error2}`).join(
1369
1430
  ""
1370
1431
  )}
1371
1432
 
@@ -1462,7 +1523,13 @@ var MicrofrontendsServer = class {
1462
1523
  filePath,
1463
1524
  cookies
1464
1525
  } = {}) {
1526
+ logger.debug("[MFE Config] Starting config inference", {
1527
+ appName,
1528
+ directory: directory || process.cwd(),
1529
+ filePath
1530
+ });
1465
1531
  if (filePath) {
1532
+ logger.debug("[MFE Config] Using explicit filePath:", filePath);
1466
1533
  return MicrofrontendsServer.fromFile({
1467
1534
  filePath,
1468
1535
  cookies
@@ -1470,16 +1537,25 @@ var MicrofrontendsServer = class {
1470
1537
  }
1471
1538
  try {
1472
1539
  const packageRoot = findPackageRoot(directory);
1540
+ logger.debug("[MFE Config] Package root:", packageRoot);
1473
1541
  const applicationContext = getApplicationContext({
1474
1542
  appName,
1475
1543
  packageRoot
1476
1544
  });
1545
+ logger.debug("[MFE Config] Application context:", applicationContext);
1477
1546
  const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1547
+ if (customConfigFilename) {
1548
+ logger.debug(
1549
+ "[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
1550
+ customConfigFilename
1551
+ );
1552
+ }
1478
1553
  const maybeConfig = findConfig({
1479
1554
  dir: packageRoot,
1480
1555
  customConfigFilename
1481
1556
  });
1482
1557
  if (maybeConfig) {
1558
+ logger.debug("[MFE Config] Config found at package root:", maybeConfig);
1483
1559
  return MicrofrontendsServer.fromFile({
1484
1560
  filePath: maybeConfig,
1485
1561
  cookies
@@ -1487,42 +1563,78 @@ var MicrofrontendsServer = class {
1487
1563
  }
1488
1564
  const repositoryRoot = findRepositoryRoot();
1489
1565
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1566
+ logger.debug(
1567
+ "[MFE Config] Repository root:",
1568
+ repositoryRoot,
1569
+ "Is monorepo:",
1570
+ isMonorepo2
1571
+ );
1490
1572
  const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1491
1573
  if (typeof configFromEnv === "string") {
1574
+ logger.debug(
1575
+ "[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
1576
+ configFromEnv
1577
+ );
1492
1578
  const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1493
1579
  if (maybeConfigFromEnv) {
1580
+ logger.debug(
1581
+ "[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
1582
+ maybeConfigFromEnv
1583
+ );
1494
1584
  return MicrofrontendsServer.fromFile({
1495
1585
  filePath: maybeConfigFromEnv,
1496
1586
  cookies
1497
1587
  });
1498
1588
  }
1499
1589
  } else {
1590
+ const vercelDir = join2(packageRoot, ".vercel");
1591
+ logger.debug(
1592
+ "[MFE Config] Searching for config in .vercel directory:",
1593
+ vercelDir
1594
+ );
1500
1595
  const maybeConfigFromVercel = findConfig({
1501
- dir: join2(packageRoot, ".vercel"),
1596
+ dir: vercelDir,
1502
1597
  customConfigFilename
1503
1598
  });
1504
1599
  if (maybeConfigFromVercel) {
1600
+ logger.debug(
1601
+ "[MFE Config] Config found in .vercel directory:",
1602
+ maybeConfigFromVercel
1603
+ );
1505
1604
  return MicrofrontendsServer.fromFile({
1506
1605
  filePath: maybeConfigFromVercel,
1507
1606
  cookies
1508
1607
  });
1509
1608
  }
1510
1609
  if (isMonorepo2) {
1610
+ logger.debug(
1611
+ "[MFE Config] Inferring microfrontends location in monorepo for application:",
1612
+ applicationContext.name
1613
+ );
1511
1614
  const defaultPackage = inferMicrofrontendsLocation({
1512
1615
  repositoryRoot,
1513
1616
  applicationContext,
1514
1617
  customConfigFilename
1515
1618
  });
1619
+ logger.debug(
1620
+ "[MFE Config] Inferred package location:",
1621
+ defaultPackage
1622
+ );
1516
1623
  const maybeConfigFromDefault = findConfig({
1517
1624
  dir: defaultPackage,
1518
1625
  customConfigFilename
1519
1626
  });
1520
1627
  if (maybeConfigFromDefault) {
1628
+ logger.debug(
1629
+ "[MFE Config] Config found in inferred package:",
1630
+ maybeConfigFromDefault
1631
+ );
1521
1632
  return MicrofrontendsServer.fromFile({
1522
1633
  filePath: maybeConfigFromDefault,
1523
1634
  cookies
1524
1635
  });
1525
1636
  }
1637
+ logger.debug("[MFE Config] No config found in inferred package");
1526
1638
  }
1527
1639
  }
1528
1640
  throw new MicrofrontendError(
@@ -1548,8 +1660,13 @@ var MicrofrontendsServer = class {
1548
1660
  cookies
1549
1661
  }) {
1550
1662
  try {
1663
+ logger.debug("[MFE Config] Reading config from file:", filePath);
1551
1664
  const configJson = fs6.readFileSync(filePath, "utf-8");
1552
1665
  const config = MicrofrontendsServer.validate(configJson);
1666
+ logger.debug(
1667
+ "[MFE Config] Config loaded with applications:",
1668
+ Object.keys(config.applications)
1669
+ );
1553
1670
  return new MicrofrontendsServer({
1554
1671
  config,
1555
1672
  overrides: cookies ? parseOverrides(cookies) : void 0