@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
@@ -6,12 +6,38 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
6
  throw new Error('Dynamic require of "' + x + '" is not supported');
7
7
  });
8
8
 
9
+ // src/bin/local-proxy-is-running.ts
10
+ function localProxyIsRunning() {
11
+ return process.env.TURBO_TASK_HAS_MFE_PROXY === "true";
12
+ }
13
+
14
+ // src/bin/logger.ts
15
+ function debug(...args) {
16
+ if (process.env.MFE_DEBUG) {
17
+ console.log(...args);
18
+ }
19
+ }
20
+ function info(...args) {
21
+ console.log(...args);
22
+ }
23
+ function warn(...args) {
24
+ console.warn(...args);
25
+ }
26
+ function error(...args) {
27
+ console.error(...args);
28
+ }
29
+ var logger = {
30
+ debug,
31
+ info,
32
+ warn,
33
+ error
34
+ };
35
+
9
36
  // src/bin/check-proxy.ts
10
37
  function displayLocalProxyInfo(port) {
11
- const { MFE_PROXY_MESSAGE_PRINTED, TURBO_TASK_HAS_MFE_PROXY } = process.env;
12
- if (TURBO_TASK_HAS_MFE_PROXY === "true" && MFE_PROXY_MESSAGE_PRINTED !== "true") {
38
+ if (localProxyIsRunning() && process.env.MFE_PROXY_MESSAGE_PRINTED !== "true") {
13
39
  process.env.MFE_PROXY_MESSAGE_PRINTED = "true";
14
- console.log(`Microfrontends Proxy running on http://localhost:${port}`);
40
+ logger.info(`Microfrontends Proxy running on http://localhost:${port}`);
15
41
  }
16
42
  }
17
43
 
@@ -206,8 +232,8 @@ import fg from "fast-glob";
206
232
 
207
233
  // src/config/microfrontends/utils/get-config-file-name.ts
208
234
  var DEFAULT_CONFIGURATION_FILENAMES = [
209
- "microfrontends.jsonc",
210
- "microfrontends.json"
235
+ "microfrontends.json",
236
+ "microfrontends.jsonc"
211
237
  ];
212
238
  function getPossibleConfigurationFilenames({
213
239
  customConfigFilename
@@ -215,7 +241,7 @@ function getPossibleConfigurationFilenames({
215
241
  if (customConfigFilename) {
216
242
  if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
217
243
  throw new Error(
218
- `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
244
+ `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.`
219
245
  );
220
246
  }
221
247
  return Array.from(
@@ -233,6 +259,10 @@ function findPackageWithMicrofrontendsConfig({
233
259
  customConfigFilename
234
260
  }) {
235
261
  const applicationName = applicationContext.name;
262
+ logger.debug(
263
+ "[MFE Config] Searching repository for configs containing application:",
264
+ applicationName
265
+ );
236
266
  try {
237
267
  const microfrontendsJsonPaths = fg.globSync(
238
268
  `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
@@ -244,6 +274,11 @@ function findPackageWithMicrofrontendsConfig({
244
274
  ignore: ["**/node_modules/**", "**/.git/**"]
245
275
  }
246
276
  );
277
+ logger.debug(
278
+ "[MFE Config] Found",
279
+ microfrontendsJsonPaths.length,
280
+ "config file(s) in repository"
281
+ );
247
282
  const matchingPaths = [];
248
283
  for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
249
284
  try {
@@ -253,19 +288,31 @@ function findPackageWithMicrofrontendsConfig({
253
288
  );
254
289
  const microfrontendsJson = parse(microfrontendsJsonContent);
255
290
  if (microfrontendsJson.applications[applicationName]) {
291
+ logger.debug(
292
+ "[MFE Config] Found application in config:",
293
+ microfrontendsJsonPath
294
+ );
256
295
  matchingPaths.push(microfrontendsJsonPath);
257
296
  } else {
258
297
  for (const [_, app] of Object.entries(
259
298
  microfrontendsJson.applications
260
299
  )) {
261
300
  if (app.packageName === applicationName) {
301
+ logger.debug(
302
+ "[MFE Config] Found application via packageName in config:",
303
+ microfrontendsJsonPath
304
+ );
262
305
  matchingPaths.push(microfrontendsJsonPath);
263
306
  }
264
307
  }
265
308
  }
266
- } catch (error) {
309
+ } catch (error2) {
267
310
  }
268
311
  }
312
+ logger.debug(
313
+ "[MFE Config] Total matching config files:",
314
+ matchingPaths.length
315
+ );
269
316
  if (matchingPaths.length > 1) {
270
317
  throw new MicrofrontendError(
271
318
  `Found multiple \`microfrontends.json\` files in the repository referencing the application "${applicationName}", but only one is allowed.
@@ -299,9 +346,9 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
299
346
  }
300
347
  const [packageJsonPath] = matchingPaths;
301
348
  return dirname(packageJsonPath);
302
- } catch (error) {
303
- if (error instanceof MicrofrontendError) {
304
- throw error;
349
+ } catch (error2) {
350
+ if (error2 instanceof MicrofrontendError) {
351
+ throw error2;
305
352
  }
306
353
  return null;
307
354
  }
@@ -346,8 +393,8 @@ function isMonorepo({
346
393
  fs2.readFileSync(packageJsonPath, "utf-8")
347
394
  );
348
395
  return packageJson.workspaces !== void 0;
349
- } catch (error) {
350
- console.error("Error determining if repository is a monorepo", error);
396
+ } catch (error2) {
397
+ logger.error("Error determining if repository is a monorepo", error2);
351
398
  return false;
352
399
  }
353
400
  }
@@ -1064,15 +1111,18 @@ import fs5 from "node:fs";
1064
1111
  import path4 from "node:path";
1065
1112
  function getApplicationContext(opts) {
1066
1113
  if (opts?.appName) {
1114
+ logger.debug("[MFE Config] Application name from appName parameter:", opts.appName);
1067
1115
  return { name: opts.appName };
1068
1116
  }
1069
1117
  if (process.env.VERCEL_PROJECT_NAME) {
1118
+ logger.debug("[MFE Config] Application name from VERCEL_PROJECT_NAME:", process.env.VERCEL_PROJECT_NAME);
1070
1119
  return {
1071
1120
  name: process.env.VERCEL_PROJECT_NAME,
1072
1121
  projectName: process.env.VERCEL_PROJECT_NAME
1073
1122
  };
1074
1123
  }
1075
1124
  if (process.env.NX_TASK_TARGET_PROJECT) {
1125
+ logger.debug("[MFE Config] Application name from NX_TASK_TARGET_PROJECT:", process.env.NX_TASK_TARGET_PROJECT);
1076
1126
  return {
1077
1127
  name: process.env.NX_TASK_TARGET_PROJECT,
1078
1128
  packageJsonName: process.env.NX_TASK_TARGET_PROJECT
@@ -1085,6 +1135,7 @@ function getApplicationContext(opts) {
1085
1135
  );
1086
1136
  const projectJson = JSON.parse(vercelProjectJsonPath);
1087
1137
  if (projectJson.projectName) {
1138
+ logger.debug("[MFE Config] Application name from .vercel/project.json:", projectJson.projectName);
1088
1139
  return {
1089
1140
  name: projectJson.projectName,
1090
1141
  projectName: projectJson.projectName
@@ -1108,6 +1159,7 @@ function getApplicationContext(opts) {
1108
1159
  }
1109
1160
  );
1110
1161
  }
1162
+ logger.debug("[MFE Config] Application name from package.json:", packageJson.name);
1111
1163
  return { name: packageJson.name, packageJsonName: packageJson.name };
1112
1164
  } catch (err) {
1113
1165
  throw MicrofrontendError.handle(err, {
@@ -1141,38 +1193,28 @@ var schema_default = {
1141
1193
  type: "object",
1142
1194
  properties: {
1143
1195
  $schema: {
1144
- type: "string"
1196
+ type: "string",
1197
+ description: "See https://openapi.vercel.sh/microfrontends.json."
1145
1198
  },
1146
1199
  version: {
1147
1200
  type: "string",
1148
- const: "1"
1149
- },
1150
- options: {
1151
- $ref: "#/definitions/Options"
1201
+ const: "1",
1202
+ description: "The version of the microfrontends config schema."
1152
1203
  },
1153
1204
  applications: {
1154
1205
  $ref: "#/definitions/ApplicationRouting",
1155
- 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"
1206
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1207
+ },
1208
+ options: {
1209
+ $ref: "#/definitions/Options",
1210
+ description: "Optional configuration options for the microfrontend."
1156
1211
  }
1157
1212
  },
1158
1213
  required: [
1159
1214
  "applications"
1160
1215
  ],
1161
- additionalProperties: false
1162
- },
1163
- Options: {
1164
- type: "object",
1165
- properties: {
1166
- disableOverrides: {
1167
- type: "boolean",
1168
- 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."
1169
- },
1170
- localProxyPort: {
1171
- type: "number",
1172
- description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1173
- }
1174
- },
1175
- additionalProperties: false
1216
+ additionalProperties: false,
1217
+ description: "The microfrontends configuration schema. See https://vercel.com/docs/microfrontends/configuration."
1176
1218
  },
1177
1219
  ApplicationRouting: {
1178
1220
  type: "object",
@@ -1180,8 +1222,9 @@ var schema_default = {
1180
1222
  $ref: "#/definitions/Application"
1181
1223
  },
1182
1224
  propertyNames: {
1183
- 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."
1184
- }
1225
+ 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."
1226
+ },
1227
+ description: "Mapping of Vercel project names to their microfrontend configurations."
1185
1228
  },
1186
1229
  Application: {
1187
1230
  anyOf: [
@@ -1191,14 +1234,15 @@ var schema_default = {
1191
1234
  {
1192
1235
  $ref: "#/definitions/ChildApplication"
1193
1236
  }
1194
- ]
1237
+ ],
1238
+ description: "The configuration for a microfrontend application. There must always be one default application."
1195
1239
  },
1196
1240
  DefaultApplication: {
1197
1241
  type: "object",
1198
1242
  properties: {
1199
1243
  packageName: {
1200
1244
  type: "string",
1201
- 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`."
1245
+ 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."
1202
1246
  },
1203
1247
  development: {
1204
1248
  $ref: "#/definitions/DefaultDevelopment",
@@ -1218,15 +1262,15 @@ var schema_default = {
1218
1262
  "number",
1219
1263
  "string"
1220
1264
  ],
1221
- 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"
1265
+ 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."
1222
1266
  },
1223
1267
  task: {
1224
1268
  type: "string",
1225
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1269
+ 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.'
1226
1270
  },
1227
1271
  fallback: {
1228
1272
  type: "string",
1229
- 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."
1273
+ 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."
1230
1274
  }
1231
1275
  },
1232
1276
  required: [
@@ -1239,7 +1283,7 @@ var schema_default = {
1239
1283
  properties: {
1240
1284
  packageName: {
1241
1285
  type: "string",
1242
- 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`."
1286
+ 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."
1243
1287
  },
1244
1288
  development: {
1245
1289
  $ref: "#/definitions/ChildDevelopment",
@@ -1247,11 +1291,11 @@ var schema_default = {
1247
1291
  },
1248
1292
  routing: {
1249
1293
  $ref: "#/definitions/Routing",
1250
- description: "Groups of path expressions that are routed to this application."
1294
+ description: "Groups of path expressions that are routed to this application.\n\nSee https://vercel.com/docs/microfrontends/path-routing."
1251
1295
  },
1252
1296
  assetPrefix: {
1253
1297
  type: "string",
1254
- 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."
1298
+ 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."
1255
1299
  }
1256
1300
  },
1257
1301
  required: [
@@ -1267,15 +1311,15 @@ var schema_default = {
1267
1311
  "number",
1268
1312
  "string"
1269
1313
  ],
1270
- 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"
1314
+ 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."
1271
1315
  },
1272
1316
  task: {
1273
1317
  type: "string",
1274
- description: "Optional task to run when starting the development server. Should reference a script in the package.json of the application."
1318
+ 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.'
1275
1319
  },
1276
1320
  fallback: {
1277
1321
  type: "string",
1278
- 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."
1322
+ 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."
1279
1323
  }
1280
1324
  },
1281
1325
  additionalProperties: false
@@ -1284,29 +1328,46 @@ var schema_default = {
1284
1328
  type: "array",
1285
1329
  items: {
1286
1330
  $ref: "#/definitions/PathGroup"
1287
- }
1331
+ },
1332
+ description: "A list of path groups that are routed to this application."
1288
1333
  },
1289
1334
  PathGroup: {
1290
1335
  type: "object",
1291
1336
  properties: {
1292
1337
  group: {
1293
1338
  type: "string",
1294
- description: "Optional group name for the paths"
1339
+ description: "Group name for the paths."
1295
1340
  },
1296
1341
  flag: {
1297
1342
  type: "string",
1298
- description: "flag name that can be used to enable/disable all paths in the group"
1343
+ 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."
1299
1344
  },
1300
1345
  paths: {
1301
1346
  type: "array",
1302
1347
  items: {
1303
1348
  type: "string"
1304
- }
1349
+ },
1350
+ description: "A list of path expressions that are routed to this application. See https://vercel.com/docs/microfrontends/path-routing#supported-path-expressions."
1305
1351
  }
1306
1352
  },
1307
1353
  required: [
1308
1354
  "paths"
1309
1355
  ],
1356
+ additionalProperties: false,
1357
+ description: "A group of paths that is routed to this application."
1358
+ },
1359
+ Options: {
1360
+ type: "object",
1361
+ properties: {
1362
+ disableOverrides: {
1363
+ type: "boolean",
1364
+ 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."
1365
+ },
1366
+ localProxyPort: {
1367
+ type: "number",
1368
+ 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."
1369
+ }
1370
+ },
1310
1371
  additionalProperties: false
1311
1372
  }
1312
1373
  }
@@ -1325,19 +1386,19 @@ function formatAjvErrors(errors) {
1325
1386
  return [];
1326
1387
  }
1327
1388
  const errorMessages = [];
1328
- for (const error of errors) {
1329
- if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1389
+ for (const error2 of errors) {
1390
+ if (error2.instancePath === "" && (error2.keyword === "anyOf" || error2.keyword === "required" && error2.params.missingProperty === "partOf")) {
1330
1391
  continue;
1331
1392
  }
1332
- const instancePath = error.instancePath.slice(1);
1393
+ const instancePath = error2.instancePath.slice(1);
1333
1394
  const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1334
- if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1395
+ if (error2.keyword === "required" && error2.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1335
1396
  errorMessages.push(
1336
1397
  `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1337
1398
  );
1338
- } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1399
+ } else if (error2.keyword === "anyOf" && instancePath.split("/").length > 2) {
1339
1400
  const anyOfErrors = errors.filter(
1340
- (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1401
+ (e) => e.instancePath === error2.instancePath && e.keyword !== "anyOf"
1341
1402
  );
1342
1403
  if (anyOfErrors.every((e) => e.keyword === "type")) {
1343
1404
  const allowedTypes = LIST_FORMATTER2.format(
@@ -1353,13 +1414,13 @@ function formatAjvErrors(errors) {
1353
1414
  `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1354
1415
  );
1355
1416
  }
1356
- } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1417
+ } else if (error2.keyword === "additionalProperties" && !(error2.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1357
1418
  errorMessages.push(
1358
- `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1419
+ `Property '${error2.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1359
1420
  );
1360
- } else if (error.keyword === "required") {
1421
+ } else if (error2.keyword === "required") {
1361
1422
  errorMessages.push(
1362
- `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1423
+ `Property '${error2.params.missingProperty}' is required ${formattedInstancePath}`
1363
1424
  );
1364
1425
  }
1365
1426
  }
@@ -1372,8 +1433,8 @@ function validateSchema(configString) {
1372
1433
  const isValid = validate(parsedConfig);
1373
1434
  if (!isValid) {
1374
1435
  throw new MicrofrontendError(
1375
- `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1376
- - ${error}`).join(
1436
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error2) => `
1437
+ - ${error2}`).join(
1377
1438
  ""
1378
1439
  )}
1379
1440
 
@@ -1470,7 +1531,13 @@ var MicrofrontendsServer = class {
1470
1531
  filePath,
1471
1532
  cookies
1472
1533
  } = {}) {
1534
+ logger.debug("[MFE Config] Starting config inference", {
1535
+ appName,
1536
+ directory: directory || process.cwd(),
1537
+ filePath
1538
+ });
1473
1539
  if (filePath) {
1540
+ logger.debug("[MFE Config] Using explicit filePath:", filePath);
1474
1541
  return MicrofrontendsServer.fromFile({
1475
1542
  filePath,
1476
1543
  cookies
@@ -1478,16 +1545,25 @@ var MicrofrontendsServer = class {
1478
1545
  }
1479
1546
  try {
1480
1547
  const packageRoot = findPackageRoot(directory);
1548
+ logger.debug("[MFE Config] Package root:", packageRoot);
1481
1549
  const applicationContext = getApplicationContext({
1482
1550
  appName,
1483
1551
  packageRoot
1484
1552
  });
1553
+ logger.debug("[MFE Config] Application context:", applicationContext);
1485
1554
  const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1555
+ if (customConfigFilename) {
1556
+ logger.debug(
1557
+ "[MFE Config] Custom config filename from VC_MICROFRONTENDS_CONFIG_FILE_NAME:",
1558
+ customConfigFilename
1559
+ );
1560
+ }
1486
1561
  const maybeConfig = findConfig({
1487
1562
  dir: packageRoot,
1488
1563
  customConfigFilename
1489
1564
  });
1490
1565
  if (maybeConfig) {
1566
+ logger.debug("[MFE Config] Config found at package root:", maybeConfig);
1491
1567
  return MicrofrontendsServer.fromFile({
1492
1568
  filePath: maybeConfig,
1493
1569
  cookies
@@ -1495,42 +1571,78 @@ var MicrofrontendsServer = class {
1495
1571
  }
1496
1572
  const repositoryRoot = findRepositoryRoot();
1497
1573
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1574
+ logger.debug(
1575
+ "[MFE Config] Repository root:",
1576
+ repositoryRoot,
1577
+ "Is monorepo:",
1578
+ isMonorepo2
1579
+ );
1498
1580
  const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1499
1581
  if (typeof configFromEnv === "string") {
1582
+ logger.debug(
1583
+ "[MFE Config] Checking VC_MICROFRONTENDS_CONFIG:",
1584
+ configFromEnv
1585
+ );
1500
1586
  const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1501
1587
  if (maybeConfigFromEnv) {
1588
+ logger.debug(
1589
+ "[MFE Config] Config loaded from VC_MICROFRONTENDS_CONFIG:",
1590
+ maybeConfigFromEnv
1591
+ );
1502
1592
  return MicrofrontendsServer.fromFile({
1503
1593
  filePath: maybeConfigFromEnv,
1504
1594
  cookies
1505
1595
  });
1506
1596
  }
1507
1597
  } else {
1598
+ const vercelDir = join2(packageRoot, ".vercel");
1599
+ logger.debug(
1600
+ "[MFE Config] Searching for config in .vercel directory:",
1601
+ vercelDir
1602
+ );
1508
1603
  const maybeConfigFromVercel = findConfig({
1509
- dir: join2(packageRoot, ".vercel"),
1604
+ dir: vercelDir,
1510
1605
  customConfigFilename
1511
1606
  });
1512
1607
  if (maybeConfigFromVercel) {
1608
+ logger.debug(
1609
+ "[MFE Config] Config found in .vercel directory:",
1610
+ maybeConfigFromVercel
1611
+ );
1513
1612
  return MicrofrontendsServer.fromFile({
1514
1613
  filePath: maybeConfigFromVercel,
1515
1614
  cookies
1516
1615
  });
1517
1616
  }
1518
1617
  if (isMonorepo2) {
1618
+ logger.debug(
1619
+ "[MFE Config] Inferring microfrontends location in monorepo for application:",
1620
+ applicationContext.name
1621
+ );
1519
1622
  const defaultPackage = inferMicrofrontendsLocation({
1520
1623
  repositoryRoot,
1521
1624
  applicationContext,
1522
1625
  customConfigFilename
1523
1626
  });
1627
+ logger.debug(
1628
+ "[MFE Config] Inferred package location:",
1629
+ defaultPackage
1630
+ );
1524
1631
  const maybeConfigFromDefault = findConfig({
1525
1632
  dir: defaultPackage,
1526
1633
  customConfigFilename
1527
1634
  });
1528
1635
  if (maybeConfigFromDefault) {
1636
+ logger.debug(
1637
+ "[MFE Config] Config found in inferred package:",
1638
+ maybeConfigFromDefault
1639
+ );
1529
1640
  return MicrofrontendsServer.fromFile({
1530
1641
  filePath: maybeConfigFromDefault,
1531
1642
  cookies
1532
1643
  });
1533
1644
  }
1645
+ logger.debug("[MFE Config] No config found in inferred package");
1534
1646
  }
1535
1647
  }
1536
1648
  throw new MicrofrontendError(
@@ -1556,8 +1668,13 @@ var MicrofrontendsServer = class {
1556
1668
  cookies
1557
1669
  }) {
1558
1670
  try {
1671
+ logger.debug("[MFE Config] Reading config from file:", filePath);
1559
1672
  const configJson = fs6.readFileSync(filePath, "utf-8");
1560
1673
  const config = MicrofrontendsServer.validate(configJson);
1674
+ logger.debug(
1675
+ "[MFE Config] Config loaded with applications:",
1676
+ Object.keys(config.applications)
1677
+ );
1561
1678
  return new MicrofrontendsServer({
1562
1679
  config,
1563
1680
  overrides: cookies ? parseOverrides(cookies) : void 0
@@ -1658,17 +1775,10 @@ function transform3(args) {
1658
1775
  };
1659
1776
  }
1660
1777
 
1661
- // src/next/utils/route-to-local-proxy.ts
1662
- function routeToLocalProxy() {
1663
- const isDevEnv = (process.env.VERCEL_ENV ?? "development") === "development";
1664
- return isDevEnv && Boolean(process.env.TURBO_TASK_HAS_MFE_PROXY);
1665
- }
1666
-
1667
1778
  // src/next/config/transforms/redirects.ts
1668
1779
  function transform4(args) {
1669
- const { next, microfrontend, opts } = args;
1670
- const isProduction2 = opts?.isProduction ?? false;
1671
- const requireLocalProxyHeader = routeToLocalProxy() && !isProduction2 && !process.env.MFE_DISABLE_LOCAL_PROXY_REWRITE;
1780
+ const { next, microfrontend } = args;
1781
+ const requireLocalProxyHeader = localProxyIsRunning() && !process.env.MFE_DISABLE_LOCAL_PROXY_REWRITE;
1672
1782
  if (requireLocalProxyHeader) {
1673
1783
  const proxyRedirects = [
1674
1784
  {
@@ -1695,17 +1805,15 @@ function transform4(args) {
1695
1805
  } else {
1696
1806
  next.redirects = async () => proxyRedirects;
1697
1807
  }
1698
- if (process.env.MFE_DEBUG) {
1699
- const indent = " ".repeat(4);
1700
- const header = "redirects";
1701
- const separator = "\u23AF".repeat(header.length);
1702
- console.log(
1703
- `${indent}${header}
1808
+ const indent = " ".repeat(4);
1809
+ const header = "redirects";
1810
+ const separator = "\u23AF".repeat(header.length);
1811
+ logger.debug(
1812
+ `${indent}${header}
1704
1813
  ${indent}${separator}
1705
1814
  ${indent} - Automatically redirecting all requests to local microfrontends proxy
1706
1815
  `
1707
- );
1708
- }
1816
+ );
1709
1817
  }
1710
1818
  return { next };
1711
1819
  }
@@ -1726,22 +1834,18 @@ function transform5(args) {
1726
1834
 
1727
1835
  // src/next/config/transforms/rewrites.ts
1728
1836
  function debugRewrites(rewrites) {
1729
- if (process.env.MFE_DEBUG) {
1730
- const indent = " ".repeat(4);
1731
- const header = "rewrites (source \u2192 destination)";
1732
- const separator = "\u23AF".repeat(header.length);
1733
- const maxSourceLength = Math.max(
1734
- ...rewrites.map((key) => key.source.length)
1735
- );
1736
- const table = rewrites.map((route, idx) => {
1737
- const paddedSource = route.source.padEnd(maxSourceLength);
1738
- return `${indent} ${idx + 1}. ${paddedSource} \u2192 ${route.destination}`;
1739
- }).join("\n");
1740
- console.log(`${indent}${header}
1837
+ const indent = " ".repeat(4);
1838
+ const header = "rewrites (source \u2192 destination)";
1839
+ const separator = "\u23AF".repeat(header.length);
1840
+ const maxSourceLength = Math.max(...rewrites.map((key) => key.source.length));
1841
+ const table = rewrites.map((route, idx) => {
1842
+ const paddedSource = route.source.padEnd(maxSourceLength);
1843
+ return `${indent} ${idx + 1}. ${paddedSource} \u2192 ${route.destination}`;
1844
+ }).join("\n");
1845
+ logger.debug(`${indent}${header}
1741
1846
  ${indent}${separator}
1742
1847
  ${table}
1743
1848
  `);
1744
- }
1745
1849
  }
1746
1850
  function rewritesMapToArr(rewrites) {
1747
1851
  return Array.from(rewrites.entries()).flatMap(([source, rewrite]) => {
@@ -1939,20 +2043,18 @@ var transforms = {
1939
2043
 
1940
2044
  // src/next/config/env.ts
1941
2045
  function debugEnv(env) {
1942
- if (process.env.MFE_DEBUG) {
1943
- const indent = " ".repeat(4);
1944
- const header = "env (key \u2192 val)";
1945
- const separator = "\u23AF".repeat(header.length);
1946
- const maxKeyLength = Math.max(...Object.keys(env).map((key) => key.length));
1947
- const table = Object.keys(env).map((key, idx) => {
1948
- const paddedKey = key.padEnd(maxKeyLength);
1949
- return `${indent} ${idx + 1}. ${paddedKey} = ${env[key]}`;
1950
- }).join("\n");
1951
- console.log(`${indent}${header}
2046
+ const indent = " ".repeat(4);
2047
+ const header = "env (key \u2192 val)";
2048
+ const separator = "\u23AF".repeat(header.length);
2049
+ const maxKeyLength = Math.max(...Object.keys(env).map((key) => key.length));
2050
+ const table = Object.keys(env).map((key, idx) => {
2051
+ const paddedKey = key.padEnd(maxKeyLength);
2052
+ return `${indent} ${idx + 1}. ${paddedKey} = ${env[key]}`;
2053
+ }).join("\n");
2054
+ logger.debug(`${indent}${header}
1952
2055
  ${indent}${separator}
1953
2056
  ${table}
1954
2057
  `);
1955
- }
1956
2058
  }
1957
2059
  function setEnvironment({
1958
2060
  app,
@@ -1988,12 +2090,6 @@ function setEnvironment({
1988
2090
  function typedEntries(obj) {
1989
2091
  return Object.entries(obj);
1990
2092
  }
1991
- function isProduction(opts) {
1992
- if (opts?.isProduction) {
1993
- return opts.isProduction();
1994
- }
1995
- return process.env.VERCEL_ENV === "production";
1996
- }
1997
2093
  function withMicrofrontends(nextConfig, opts) {
1998
2094
  if (opts?.debug) {
1999
2095
  process.env.MFE_DEBUG = "true";
@@ -2008,7 +2104,7 @@ function withMicrofrontends(nextConfig, opts) {
2008
2104
  let next = { ...nextConfig };
2009
2105
  for (const [key, transform8] of typedEntries(transforms)) {
2010
2106
  if (opts?.skipTransforms?.includes(key)) {
2011
- console.log(`Skipping ${key} transform`);
2107
+ logger.info(`Skipping ${key} transform`);
2012
2108
  continue;
2013
2109
  }
2014
2110
  try {
@@ -2017,13 +2113,12 @@ function withMicrofrontends(nextConfig, opts) {
2017
2113
  next,
2018
2114
  microfrontend: microfrontends.config,
2019
2115
  opts: {
2020
- isProduction: isProduction(opts),
2021
2116
  supportPagesRouter: opts?.supportPagesRouter
2022
2117
  }
2023
2118
  });
2024
2119
  next = transformedConfig.next;
2025
2120
  } catch (e) {
2026
- console.error("Error transforming next config", e);
2121
+ logger.error("Error transforming next config", e);
2027
2122
  throw e;
2028
2123
  }
2029
2124
  }