@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
@@ -191,10 +191,32 @@ import { readFileSync } from "node:fs";
191
191
  import { parse } from "jsonc-parser";
192
192
  import fg from "fast-glob";
193
193
 
194
+ // src/bin/logger.ts
195
+ function debug(...args) {
196
+ if (process.env.MFE_DEBUG) {
197
+ console.log(...args);
198
+ }
199
+ }
200
+ function info(...args) {
201
+ console.log(...args);
202
+ }
203
+ function warn(...args) {
204
+ console.warn(...args);
205
+ }
206
+ function error(...args) {
207
+ console.error(...args);
208
+ }
209
+ var logger = {
210
+ debug,
211
+ info,
212
+ warn,
213
+ error
214
+ };
215
+
194
216
  // src/config/microfrontends/utils/get-config-file-name.ts
195
217
  var DEFAULT_CONFIGURATION_FILENAMES = [
196
- "microfrontends.jsonc",
197
- "microfrontends.json"
218
+ "microfrontends.json",
219
+ "microfrontends.jsonc"
198
220
  ];
199
221
  function getPossibleConfigurationFilenames({
200
222
  customConfigFilename
@@ -202,7 +224,7 @@ function getPossibleConfigurationFilenames({
202
224
  if (customConfigFilename) {
203
225
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
204
226
  throw new Error(
205
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
227
+ `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.`
206
228
  );
207
229
  }
208
230
  return Array.from(
@@ -220,6 +242,10 @@ function findPackageWithMicrofrontendsConfig({
220
242
  customConfigFilename
221
243
  }) {
222
244
  const applicationName = applicationContext.name;
245
+ logger.debug(
246
+ "[MFE Config] Searching repository for configs containing application:",
247
+ applicationName
248
+ );
223
249
  try {
224
250
  const microfrontendsJsonPaths = fg.globSync(
225
251
  `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
@@ -231,6 +257,11 @@ function findPackageWithMicrofrontendsConfig({
231
257
  ignore: ["**/node_modules/**", "**/.git/**"]
232
258
  }
233
259
  );
260
+ logger.debug(
261
+ "[MFE Config] Found",
262
+ microfrontendsJsonPaths.length,
263
+ "config file(s) in repository"
264
+ );
234
265
  const matchingPaths = [];
235
266
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
236
267
  try {
@@ -240,19 +271,31 @@ function findPackageWithMicrofrontendsConfig({
240
271
  );
241
272
  const microfrontendsJson = parse(microfrontendsJsonContent);
242
273
  if (microfrontendsJson.applications[applicationName]) {
274
+ logger.debug(
275
+ "[MFE Config] Found application in config:",
276
+ microfrontendsJsonPath
277
+ );
243
278
  matchingPaths.push(microfrontendsJsonPath);
244
279
  } else {
245
280
  for (const [_, app] of Object.entries(
246
281
  microfrontendsJson.applications
247
282
  )) {
248
283
  if (app.packageName === applicationName) {
284
+ logger.debug(
285
+ "[MFE Config] Found application via packageName in config:",
286
+ microfrontendsJsonPath
287
+ );
249
288
  matchingPaths.push(microfrontendsJsonPath);
250
289
  }
251
290
  }
252
291
  }
253
- } catch (error) {
292
+ } catch (error2) {
254
293
  }
255
294
  }
295
+ logger.debug(
296
+ "[MFE Config] Total matching config files:",
297
+ matchingPaths.length
298
+ );
256
299
  if (matchingPaths.length > 1) {
257
300
  throw new MicrofrontendError(
258
301
  `Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
@@ -286,9 +329,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
286
329
  }
287
330
  const [packageJsonPath] = matchingPaths;
288
331
  return dirname(packageJsonPath);
289
- } catch (error) {
290
- if (error instanceof MicrofrontendError) {
291
- throw error;
332
+ } catch (error2) {
333
+ if (error2 instanceof MicrofrontendError) {
334
+ throw error2;
292
335
  }
293
336
  return null;
294
337
  }
@@ -333,8 +376,8 @@ function isMonorepo({
333
376
  fs2.readFileSync(packageJsonPath, "utf-8")
334
377
  );
335
378
  return packageJson.workspaces !== void 0;
336
- } catch (error) {
337
- console.error("Error determining if repository is a monorepo", error);
379
+ } catch (error2) {
380
+ logger.error("Error determining if repository is a monorepo", error2);
338
381
  return false;
339
382
  }
340
383
  }
@@ -1051,15 +1094,18 @@ import fs5 from "node:fs";
1051
1094
  import path4 from "node:path";
1052
1095
  function getApplicationContext(opts) {
1053
1096
  if (opts?.appName) {
1097
+ logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
1054
1098
  return { name: opts.appName };
1055
1099
  }
1056
1100
  if (process.env.VERCEL_PROJECT_NAME) {
1101
+ logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
1057
1102
  return {
1058
1103
  name: process.env.VERCEL_PROJECT_NAME,
1059
1104
  projectName: process.env.VERCEL_PROJECT_NAME
1060
1105
  };
1061
1106
  }
1062
1107
  if (process.env.NX_TASK_TARGET_PROJECT) {
1108
+ logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
1063
1109
  return {
1064
1110
  name: process.env.NX_TASK_TARGET_PROJECT,
1065
1111
  packageJsonName: process.env.NX_TASK_TARGET_PROJECT
@@ -1072,6 +1118,7 @@ function getApplicationContext(opts) {
1072
1118
  );
1073
1119
  const projectJson = JSON.parse(vercelProjectJsonPath);
1074
1120
  if (projectJson.projectName) {
1121
+ logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
1075
1122
  return {
1076
1123
  name: projectJson.projectName,
1077
1124
  projectName: projectJson.projectName
@@ -1095,6 +1142,7 @@ function getApplicationContext(opts) {
1095
1142
  }
1096
1143
  );
1097
1144
  }
1145
+ logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
1098
1146
  return { name: packageJson.name, packageJsonName: packageJson.name };
1099
1147
  } catch (err) {
1100
1148
  throw MicrofrontendError.handle(err, {
@@ -1128,38 +1176,28 @@ var schema_default = {
1128
1176
  type: "object",
1129
1177
  properties: {
1130
1178
  $schema: {
1131
- type: "string"
1179
+ type: "string",
1180
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1132
1181
  },
1133
1182
  version: {
1134
1183
  type: "string",
1135
- const: "1"
1136
- },
1137
- options: {
1138
- $ref: "#/definitions/Options"
1184
+ const: "1",
1185
+ description: "The version of the microfrontends config schema."
1139
1186
  },
1140
1187
  applications: {
1141
1188
  $ref: "#/definitions/ApplicationRouting",
1142
- 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"
1189
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1190
+ },
1191
+ options: {
1192
+ $ref: "#/definitions/Options",
1193
+ description: "Optional configuration options for the microfrontend."
1143
1194
  }
1144
1195
  },
1145
1196
  required: [
1146
1197
  "applications"
1147
1198
  ],
1148
- additionalProperties: false
1149
- },
1150
- Options: {
1151
- type: "object",
1152
- properties: {
1153
- disableOverrides: {
1154
- type: "boolean",
1155
- 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."
1156
- },
1157
- localProxyPort: {
1158
- type: "number",
1159
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1160
- }
1161
- },
1162
- additionalProperties: false
1199
+ additionalProperties: false,
1200
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1163
1201
  },
1164
1202
  ApplicationRouting: {
1165
1203
  type: "object",
@@ -1167,8 +1205,9 @@ var schema_default = {
1167
1205
  $ref: "#/definitions/Application"
1168
1206
  },
1169
1207
  propertyNames: {
1170
- 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."
1171
- }
1208
+ 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."
1209
+ },
1210
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1172
1211
  },
1173
1212
  Application: {
1174
1213
  anyOf: [
@@ -1178,14 +1217,15 @@ var schema_default = {
1178
1217
  {
1179
1218
  $ref: "#/definitions/ChildApplication"
1180
1219
  }
1181
- ]
1220
+ ],
1221
+ description: "The configuration for a microfrontend application. There must always be one default application."
1182
1222
  },
1183
1223
  DefaultApplication: {
1184
1224
  type: "object",
1185
1225
  properties: {
1186
1226
  packageName: {
1187
1227
  type: "string",
1188
- 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`."
1228
+ 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."
1189
1229
  },
1190
1230
  development: {
1191
1231
  $ref: "#/definitions/DefaultDevelopment",
@@ -1205,15 +1245,15 @@ var schema_default = {
1205
1245
  "number",
1206
1246
  "string"
1207
1247
  ],
1208
- 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"
1248
+ 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."
1209
1249
  },
1210
1250
  task: {
1211
1251
  type: "string",
1212
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1252
+ 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.'
1213
1253
  },
1214
1254
  fallback: {
1215
1255
  type: "string",
1216
- 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."
1256
+ 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."
1217
1257
  }
1218
1258
  },
1219
1259
  required: [
@@ -1226,7 +1266,7 @@ var schema_default = {
1226
1266
  properties: {
1227
1267
  packageName: {
1228
1268
  type: "string",
1229
- 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`."
1269
+ 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."
1230
1270
  },
1231
1271
  development: {
1232
1272
  $ref: "#/definitions/ChildDevelopment",
@@ -1234,11 +1274,11 @@ var schema_default = {
1234
1274
  },
1235
1275
  routing: {
1236
1276
  $ref: "#/definitions/Routing",
1237
- description: "Groups of path expressions that are routed to this application."
1277
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1238
1278
  },
1239
1279
  assetPrefix: {
1240
1280
  type: "string",
1241
- 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."
1281
+ 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."
1242
1282
  }
1243
1283
  },
1244
1284
  required: [
@@ -1254,15 +1294,15 @@ var schema_default = {
1254
1294
  "number",
1255
1295
  "string"
1256
1296
  ],
1257
- 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"
1297
+ 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."
1258
1298
  },
1259
1299
  task: {
1260
1300
  type: "string",
1261
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1301
+ 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.'
1262
1302
  },
1263
1303
  fallback: {
1264
1304
  type: "string",
1265
- 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."
1305
+ 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."
1266
1306
  }
1267
1307
  },
1268
1308
  additionalProperties: false
@@ -1271,29 +1311,46 @@ var schema_default = {
1271
1311
  type: "array",
1272
1312
  items: {
1273
1313
  $ref: "#/definitions/PathGroup"
1274
- }
1314
+ },
1315
+ description: "A list of path groups that are routed to this application."
1275
1316
  },
1276
1317
  PathGroup: {
1277
1318
  type: "object",
1278
1319
  properties: {
1279
1320
  group: {
1280
1321
  type: "string",
1281
- description: "Optional group name for the paths"
1322
+ description: "Group name for the paths."
1282
1323
  },
1283
1324
  flag: {
1284
1325
  type: "string",
1285
- description: "flag name that can be used to enable/disable all paths in the group"
1326
+ 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."
1286
1327
  },
1287
1328
  paths: {
1288
1329
  type: "array",
1289
1330
  items: {
1290
1331
  type: "string"
1291
- }
1332
+ },
1333
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1292
1334
  }
1293
1335
  },
1294
1336
  required: [
1295
1337
  "paths"
1296
1338
  ],
1339
+ additionalProperties: false,
1340
+ description: "A group of paths that is routed to this application."
1341
+ },
1342
+ Options: {
1343
+ type: "object",
1344
+ properties: {
1345
+ disableOverrides: {
1346
+ type: "boolean",
1347
+ 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."
1348
+ },
1349
+ localProxyPort: {
1350
+ type: "number",
1351
+ 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."
1352
+ }
1353
+ },
1297
1354
  additionalProperties: false
1298
1355
  }
1299
1356
  }
@@ -1312,19 +1369,19 @@ function formatAjvErrors(errors) {
1312
1369
  return [];
1313
1370
  }
1314
1371
  const errorMessages = [];
1315
- for (const error of errors) {
1316
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1372
+ for (const error2 of errors) {
1373
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1317
1374
  continue;
1318
1375
  }
1319
- const instancePath = error.instancePath.slice(1);
1376
+ const instancePath = error2.instancePath.slice(1);
1320
1377
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1321
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1378
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1322
1379
  errorMessages.push(
1323
1380
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1324
1381
  );
1325
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1382
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1326
1383
  const anyOfErrors = errors.filter(
1327
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1384
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1328
1385
  );
1329
1386
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1330
1387
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1340,13 +1397,13 @@ function formatAjvErrors(errors) {
1340
1397
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1341
1398
  );
1342
1399
  }
1343
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1400
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1344
1401
  errorMessages.push(
1345
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1402
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1346
1403
  );
1347
- } else if (error.keyword === "required") {
1404
+ } else if (error2.keyword === "required") {
1348
1405
  errorMessages.push(
1349
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1406
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1350
1407
  );
1351
1408
  }
1352
1409
  }
@@ -1359,8 +1416,8 @@ function validateSchema(configString) {
1359
1416
  const isValid = validate(parsedConfig);
1360
1417
  if (!isValid) {
1361
1418
  throw new MicrofrontendError(
1362
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1363
- - ${error}`).join(
1419
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1420
+ - ${error2}`).join(
1364
1421
  ""
1365
1422
  )}
1366
1423
 
@@ -1457,7 +1514,13 @@ var MicrofrontendsServer = class {
1457
1514
  filePath,
1458
1515
  cookies
1459
1516
  } = {}) {
1517
+ logger.debug("[MFE Config] Starting config inference", {
1518
+ appName,
1519
+ directory: directory || process.cwd(),
1520
+ filePath
1521
+ });
1460
1522
  if (filePath) {
1523
+ logger.debug("[MFE Config] Using explicit filePath:", filePath);
1461
1524
  return MicrofrontendsServer.fromFile({
1462
1525
  filePath,
1463
1526
  cookies
@@ -1465,16 +1528,25 @@ var MicrofrontendsServer = class {
1465
1528
  }
1466
1529
  try {
1467
1530
  const packageRoot = findPackageRoot(directory);
1531
+ logger.debug("[MFE Config] Package root:", packageRoot);
1468
1532
  const applicationContext = getApplicationContext({
1469
1533
  appName,
1470
1534
  packageRoot
1471
1535
  });
1536
+ logger.debug("[MFE Config] Application context:", applicationContext);
1472
1537
  const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1538
+ if (customConfigFilename) {
1539
+ logger.debug(
1540
+ "[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
1541
+ customConfigFilename
1542
+ );
1543
+ }
1473
1544
  const maybeConfig = findConfig({
1474
1545
  dir: packageRoot,
1475
1546
  customConfigFilename
1476
1547
  });
1477
1548
  if (maybeConfig) {
1549
+ logger.debug("[MFE Config] Config found at package root:", maybeConfig);
1478
1550
  return MicrofrontendsServer.fromFile({
1479
1551
  filePath: maybeConfig,
1480
1552
  cookies
@@ -1482,42 +1554,78 @@ var MicrofrontendsServer = class {
1482
1554
  }
1483
1555
  const repositoryRoot = findRepositoryRoot();
1484
1556
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1557
+ logger.debug(
1558
+ "[MFE Config] Repository root:",
1559
+ repositoryRoot,
1560
+ "Is monorepo:",
1561
+ isMonorepo2
1562
+ );
1485
1563
  const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1486
1564
  if (typeof configFromEnv === "string") {
1565
+ logger.debug(
1566
+ "[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
1567
+ configFromEnv
1568
+ );
1487
1569
  const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1488
1570
  if (maybeConfigFromEnv) {
1571
+ logger.debug(
1572
+ "[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
1573
+ maybeConfigFromEnv
1574
+ );
1489
1575
  return MicrofrontendsServer.fromFile({
1490
1576
  filePath: maybeConfigFromEnv,
1491
1577
  cookies
1492
1578
  });
1493
1579
  }
1494
1580
  } else {
1581
+ const vercelDir = join2(packageRoot, ".vercel");
1582
+ logger.debug(
1583
+ "[MFE Config] Searching for config in .vercel directory:",
1584
+ vercelDir
1585
+ );
1495
1586
  const maybeConfigFromVercel = findConfig({
1496
- dir: join2(packageRoot, ".vercel"),
1587
+ dir: vercelDir,
1497
1588
  customConfigFilename
1498
1589
  });
1499
1590
  if (maybeConfigFromVercel) {
1591
+ logger.debug(
1592
+ "[MFE Config] Config found in .vercel directory:",
1593
+ maybeConfigFromVercel
1594
+ );
1500
1595
  return MicrofrontendsServer.fromFile({
1501
1596
  filePath: maybeConfigFromVercel,
1502
1597
  cookies
1503
1598
  });
1504
1599
  }
1505
1600
  if (isMonorepo2) {
1601
+ logger.debug(
1602
+ "[MFE Config] Inferring microfrontends location in monorepo for application:",
1603
+ applicationContext.name
1604
+ );
1506
1605
  const defaultPackage = inferMicrofrontendsLocation({
1507
1606
  repositoryRoot,
1508
1607
  applicationContext,
1509
1608
  customConfigFilename
1510
1609
  });
1610
+ logger.debug(
1611
+ "[MFE Config] Inferred package location:",
1612
+ defaultPackage
1613
+ );
1511
1614
  const maybeConfigFromDefault = findConfig({
1512
1615
  dir: defaultPackage,
1513
1616
  customConfigFilename
1514
1617
  });
1515
1618
  if (maybeConfigFromDefault) {
1619
+ logger.debug(
1620
+ "[MFE Config] Config found in inferred package:",
1621
+ maybeConfigFromDefault
1622
+ );
1516
1623
  return MicrofrontendsServer.fromFile({
1517
1624
  filePath: maybeConfigFromDefault,
1518
1625
  cookies
1519
1626
  });
1520
1627
  }
1628
+ logger.debug("[MFE Config] No config found in inferred package");
1521
1629
  }
1522
1630
  }
1523
1631
  throw new MicrofrontendError(
@@ -1543,8 +1651,13 @@ var MicrofrontendsServer = class {
1543
1651
  cookies
1544
1652
  }) {
1545
1653
  try {
1654
+ logger.debug("[MFE Config] Reading config from file:", filePath);
1546
1655
  const configJson = fs6.readFileSync(filePath, "utf-8");
1547
1656
  const config = MicrofrontendsServer.validate(configJson);
1657
+ logger.debug(
1658
+ "[MFE Config] Config loaded with applications:",
1659
+ Object.keys(config.applications)
1660
+ );
1548
1661
  return new MicrofrontendsServer({
1549
1662
  config,
1550
1663
  overrides: cookies ? parseOverrides(cookies) : void 0