@vercel/microfrontends 0.17.4 → 0.19.0

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 (53) hide show
  1. package/README.md +7 -159
  2. package/dist/bin/cli.cjs +202 -139
  3. package/dist/config.cjs +103 -57
  4. package/dist/config.cjs.map +1 -1
  5. package/dist/config.d.ts +4 -4
  6. package/dist/config.js +103 -57
  7. package/dist/config.js.map +1 -1
  8. package/dist/{index-f094deb1.d.ts → index-09b1ddf9.d.ts} +16 -19
  9. package/dist/{index-5fcf0863.d.ts → index-2f78c0ca.d.ts} +44 -17
  10. package/dist/microfrontends/server.cjs +180 -133
  11. package/dist/microfrontends/server.cjs.map +1 -1
  12. package/dist/microfrontends/server.d.ts +4 -4
  13. package/dist/microfrontends/server.js +180 -133
  14. package/dist/microfrontends/server.js.map +1 -1
  15. package/dist/microfrontends.cjs +104 -58
  16. package/dist/microfrontends.cjs.map +1 -1
  17. package/dist/microfrontends.d.ts +4 -4
  18. package/dist/microfrontends.js +104 -58
  19. package/dist/microfrontends.js.map +1 -1
  20. package/dist/next/client.cjs +1 -1
  21. package/dist/next/client.cjs.map +1 -1
  22. package/dist/next/client.d.ts +1 -1
  23. package/dist/next/client.js +1 -1
  24. package/dist/next/client.js.map +1 -1
  25. package/dist/next/config.cjs +197 -145
  26. package/dist/next/config.cjs.map +1 -1
  27. package/dist/next/config.js +197 -145
  28. package/dist/next/config.js.map +1 -1
  29. package/dist/next/endpoints.d.ts +2 -2
  30. package/dist/next/middleware.cjs +121 -80
  31. package/dist/next/middleware.cjs.map +1 -1
  32. package/dist/next/middleware.js +121 -80
  33. package/dist/next/middleware.js.map +1 -1
  34. package/dist/next/testing.cjs +110 -63
  35. package/dist/next/testing.cjs.map +1 -1
  36. package/dist/next/testing.d.ts +4 -4
  37. package/dist/next/testing.js +110 -63
  38. package/dist/next/testing.js.map +1 -1
  39. package/dist/overrides.d.ts +3 -3
  40. package/dist/schema.d.ts +1 -1
  41. package/dist/{types-5900be7c.d.ts → types-4ef2bddb.d.ts} +1 -1
  42. package/dist/{types-ecd7b91b.d.ts → types-b6d38aea.d.ts} +1 -1
  43. package/dist/utils/mfe-port.cjs +181 -134
  44. package/dist/utils/mfe-port.cjs.map +1 -1
  45. package/dist/utils/mfe-port.js +181 -134
  46. package/dist/utils/mfe-port.js.map +1 -1
  47. package/dist/validation.cjs +74 -73
  48. package/dist/validation.cjs.map +1 -1
  49. package/dist/validation.d.ts +1 -1
  50. package/dist/validation.js +74 -73
  51. package/dist/validation.js.map +1 -1
  52. package/package.json +19 -3
  53. package/schema/schema.json +80 -73
package/dist/bin/cli.cjs CHANGED
@@ -29,9 +29,14 @@ var import_commander = require("commander");
29
29
  // package.json
30
30
  var package_default = {
31
31
  name: "@vercel/microfrontends",
32
- version: "0.17.4",
32
+ version: "0.19.0",
33
33
  private: false,
34
- description: "Defines configuration and utilities for micro-frontend development",
34
+ description: "Defines configuration and utilities for microfrontends development",
35
+ keywords: [
36
+ "microfrontends",
37
+ "Next.js"
38
+ ],
39
+ homepage: "https://vercel.com/docs/microfrontends",
35
40
  repository: {
36
41
  type: "git",
37
42
  url: "https://github.com/vercel/front.git",
@@ -186,7 +191,7 @@ var package_default = {
186
191
  "eslint-config-custom": "workspace:*",
187
192
  jest: "^29.7.0",
188
193
  "jest-environment-jsdom": "29.2.2",
189
- next: "15.2.0-canary.32",
194
+ next: "15.1.6",
190
195
  react: "19.0.0",
191
196
  "react-dom": "19.0.0",
192
197
  "ts-config": "workspace:*",
@@ -201,6 +206,17 @@ var package_default = {
201
206
  next: ">=13",
202
207
  react: ">=17.0.0",
203
208
  "react-dom": ">=17.0.0"
209
+ },
210
+ peerDependenciesMeta: {
211
+ next: {
212
+ optional: true
213
+ },
214
+ react: {
215
+ optional: true
216
+ },
217
+ "react-dom": {
218
+ optional: true
219
+ }
204
220
  }
205
221
  };
206
222
 
@@ -220,7 +236,7 @@ function isDefaultApp(a) {
220
236
  // src/config/errors.ts
221
237
  var MicrofrontendError = class extends Error {
222
238
  constructor(message, opts) {
223
- super(message);
239
+ super(message, { cause: opts?.cause });
224
240
  this.name = "MicrofrontendsError";
225
241
  this.source = opts?.source ?? "@vercel/microfrontends";
226
242
  this.type = opts?.type ?? "unknown";
@@ -321,7 +337,8 @@ var validateConfigPaths = (applicationConfigsById) => {
321
337
  if (isDefaultApp(app)) {
322
338
  continue;
323
339
  }
324
- for (const pathMatch of app.routing) {
340
+ const childApp = app;
341
+ for (const pathMatch of childApp.routing) {
325
342
  for (const path6 of pathMatch.paths) {
326
343
  const maybeError = validatePathExpression(path6);
327
344
  if (maybeError) {
@@ -341,33 +358,31 @@ var validateConfigPaths = (applicationConfigsById) => {
341
358
  }
342
359
  }
343
360
  const entries = Array.from(pathsByApplicationId.entries());
344
- entries.forEach(([path6, { applications: ids, matcher, applicationId }]) => {
361
+ for (const [path6, { applications: ids, matcher, applicationId }] of entries) {
345
362
  if (ids.length > 1) {
346
363
  errors.push(
347
364
  `Duplicate path "${path6}" for applications "${ids.join(", ")}"`
348
365
  );
349
366
  }
350
- entries.forEach(
351
- ([
352
- matchPath,
353
- { applications: matchIds, applicationId: matchApplicationId }
354
- ]) => {
355
- if (path6 === matchPath) {
356
- return;
357
- }
358
- if (applicationId === matchApplicationId) {
359
- return;
360
- }
361
- if (matcher.test(matchPath)) {
362
- const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
363
- const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
364
- errors.push(
365
- `Overlapping path detected between ${source} and ${destination}`
366
- );
367
- }
367
+ for (const [
368
+ matchPath,
369
+ { applications: matchIds, applicationId: matchApplicationId }
370
+ ] of entries) {
371
+ if (path6 === matchPath) {
372
+ continue;
368
373
  }
369
- );
370
- });
374
+ if (applicationId === matchApplicationId) {
375
+ continue;
376
+ }
377
+ if (matcher.test(matchPath)) {
378
+ const source = `"${path6}" of application${ids.length > 0 ? "s" : ""} ${ids.join(", ")}`;
379
+ const destination = `"${matchPath}" of application${matchIds.length > 0 ? "s" : ""} ${matchIds.join(", ")}`;
380
+ errors.push(
381
+ `Overlapping path detected between ${source} and ${destination}`
382
+ );
383
+ }
384
+ }
385
+ }
371
386
  if (errors.length) {
372
387
  throw new MicrofrontendError(`Invalid paths: ${errors.join(", ")}`, {
373
388
  type: "config",
@@ -436,7 +451,7 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
436
451
  const numApplicationsWithoutRouting = numApplications - numApplicationsWithRouting;
437
452
  if (numApplicationsWithoutRouting === 0) {
438
453
  throw new MicrofrontendError(
439
- `No default application found. At least one application needs to be the default by omitting routing.`,
454
+ "No default application found. At least one application needs to be the default by omitting routing.",
440
455
  { type: "config", subtype: "no_default_application" }
441
456
  );
442
457
  }
@@ -482,47 +497,80 @@ function generatePortFromName({
482
497
  // src/config/microfrontends-config/isomorphic/host.ts
483
498
  var Host = class {
484
499
  constructor(hostConfig, options) {
485
- const { protocol = "https", host, port } = hostConfig;
486
- this.protocol = protocol;
487
- this.host = host;
488
- this.port = Host.getPort({ port, protocol: this.protocol });
500
+ if (typeof hostConfig === "string") {
501
+ ({
502
+ protocol: this.protocol,
503
+ host: this.host,
504
+ port: this.port
505
+ } = Host.parseUrl(hostConfig));
506
+ } else {
507
+ const { protocol = "https", host, port } = hostConfig;
508
+ this.protocol = protocol;
509
+ this.host = host;
510
+ this.port = port;
511
+ }
489
512
  this.local = options?.isLocal;
490
513
  }
491
- isLocal() {
492
- return this.local || this.host === "localhost" || this.host === "127.0.0.1";
493
- }
494
- static getPort({
495
- protocol,
496
- port
497
- }) {
498
- if (!port) {
499
- if (protocol === "http") {
500
- return 80;
501
- }
502
- return 443;
514
+ static parseUrl(url) {
515
+ let hostToParse = url;
516
+ if (!/^https?:\/\//.exec(hostToParse)) {
517
+ hostToParse = `https://${hostToParse}`;
518
+ }
519
+ const parsed = new URL(hostToParse);
520
+ if (!parsed.hostname) {
521
+ throw new Error(Host.getMicrofrontendsError(url, "requires a host"));
503
522
  }
504
- return port;
523
+ if (parsed.hash) {
524
+ throw new Error(
525
+ Host.getMicrofrontendsError(url, "cannot have a fragment")
526
+ );
527
+ }
528
+ if (parsed.username || parsed.password) {
529
+ throw new Error(
530
+ Host.getMicrofrontendsError(
531
+ url,
532
+ "cannot have authentication credentials (username and/or password)"
533
+ )
534
+ );
535
+ }
536
+ if (parsed.pathname !== "/") {
537
+ throw new Error(Host.getMicrofrontendsError(url, "cannot have a path"));
538
+ }
539
+ if (parsed.search) {
540
+ throw new Error(
541
+ Host.getMicrofrontendsError(url, "cannot have query parameters")
542
+ );
543
+ }
544
+ const protocol = parsed.protocol.slice(0, -1);
545
+ return {
546
+ protocol,
547
+ host: parsed.hostname,
548
+ port: parsed.port ? Number.parseInt(parsed.port) : void 0
549
+ };
550
+ }
551
+ static getMicrofrontendsError(url, message) {
552
+ return `Microfrontends configuration error: the URL ${url} in your microfrontends.json ${message}.`;
505
553
  }
506
- isDefaultPort() {
507
- return this.port === Host.getPort({ protocol: this.protocol });
554
+ isLocal() {
555
+ return this.local || this.host === "localhost" || this.host === "127.0.0.1";
508
556
  }
509
- toString(opts = {}) {
510
- const url = this.toUrl(opts);
557
+ toString() {
558
+ const url = this.toUrl();
511
559
  return url.toString().replace(/\/$/, "");
512
560
  }
513
- toUrl(opts = {}) {
514
- const { includeDefaultPort } = opts;
515
- const url = `${this.protocol}://${this.host}${this.isDefaultPort() && !includeDefaultPort ? "" : `:${this.port}`}`;
561
+ toUrl() {
562
+ const url = `${this.protocol}://${this.host}${this.port ? `:${this.port}` : ""}`;
516
563
  return new URL(url);
517
564
  }
518
565
  };
519
566
  var LocalHost = class extends Host {
520
567
  constructor({
521
568
  appName,
569
+ localPort,
522
570
  ...hostConfig
523
571
  }) {
524
572
  const host = hostConfig.host ?? "localhost";
525
- const port = hostConfig.port ?? generatePortFromName({ name: appName });
573
+ const port = localPort ?? hostConfig.port ?? generatePortFromName({ name: appName });
526
574
  const protocol = hostConfig.protocol ?? "http";
527
575
  super({ protocol, host, port });
528
576
  }
@@ -539,12 +587,17 @@ var Application = class {
539
587
  this.development = {
540
588
  local: new LocalHost({
541
589
  appName: name,
590
+ localPort: app.development?.localPort,
542
591
  ...app.development?.local
543
592
  }),
544
593
  fallback: app.development?.fallback ? new Host(app.development.fallback) : void 0
545
594
  };
546
- this.production = app.production ? new Host(app.production) : void 0;
547
- this.vercel = app.vercel;
595
+ if (app.development?.fallback) {
596
+ this.fallback = new Host(app.development.fallback);
597
+ } else if (app.production) {
598
+ this.fallback = new Host(app.production);
599
+ }
600
+ this.projectId = app.projectId ?? app.vercel?.projectId;
548
601
  this.overrides = overrides?.environment ? {
549
602
  environment: new Host(overrides.environment)
550
603
  } : void 0;
@@ -572,7 +625,16 @@ var DefaultApplication = class extends Application {
572
625
  isDefault: true
573
626
  });
574
627
  this.default = true;
575
- this.production = new Host(app.production);
628
+ const fallbackHost = app.development?.fallback ?? app.production;
629
+ if (fallbackHost === void 0) {
630
+ throw new Error(
631
+ "`app.production` or `app.development.fallback` must be set in the default application in microfrontends.json."
632
+ );
633
+ }
634
+ this.fallback = new Host(fallbackHost);
635
+ if (app.production) {
636
+ this.production = new Host(app.production);
637
+ }
576
638
  }
577
639
  getAssetPrefix() {
578
640
  return "";
@@ -761,7 +823,7 @@ var MicrofrontendConfigIsomorphic = class {
761
823
  }
762
824
  if (isMainConfig(config) && !this.defaultApplication) {
763
825
  throw new MicrofrontendError(
764
- `Could not find default application in microfrontends configuration`,
826
+ "Could not find default application in microfrontends configuration",
765
827
  {
766
828
  type: "application",
767
829
  subtype: "not_found"
@@ -837,11 +899,11 @@ var MicrofrontendConfigIsomorphic = class {
837
899
  return app;
838
900
  }
839
901
  getApplicationByProjectId(projectId) {
840
- if (this.defaultApplication?.vercel?.projectId === projectId) {
902
+ if (this.defaultApplication?.projectId === projectId) {
841
903
  return this.defaultApplication;
842
904
  }
843
905
  return Object.values(this.childApplications).find(
844
- (app) => app.vercel?.projectId === projectId
906
+ (app) => app.projectId === projectId
845
907
  );
846
908
  }
847
909
  /**
@@ -851,7 +913,7 @@ var MicrofrontendConfigIsomorphic = class {
851
913
  getDefaultApplication() {
852
914
  if (!this.defaultApplication) {
853
915
  throw new MicrofrontendError(
854
- `Could not find default application in microfrontends configuration`,
916
+ "Could not find default application in microfrontends configuration",
855
917
  {
856
918
  type: "application",
857
919
  subtype: "not_found"
@@ -864,7 +926,7 @@ var MicrofrontendConfigIsomorphic = class {
864
926
  * Returns the configured port for the local proxy
865
927
  */
866
928
  getLocalProxyPort() {
867
- return this.config.options?.localProxy?.port ?? DEFAULT_LOCAL_PROXY_PORT;
929
+ return this.config.options?.localProxyPort ?? this.config.options?.localProxy?.port ?? DEFAULT_LOCAL_PROXY_PORT;
868
930
  }
869
931
  /**
870
932
  * Serializes the class back to the Schema type.
@@ -925,7 +987,7 @@ var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
925
987
  }
926
988
  if (!defaultApplication) {
927
989
  throw new MicrofrontendError(
928
- `Could not find default application in microfrontends configuration`,
990
+ "Could not find default application in microfrontends configuration",
929
991
  {
930
992
  type: "application",
931
993
  subtype: "not_found"
@@ -1234,24 +1296,12 @@ var schema_default = {
1234
1296
  options: {
1235
1297
  $ref: "#/definitions/Options"
1236
1298
  },
1237
- remotes: {
1238
- type: "object",
1239
- additionalProperties: {
1240
- $ref: "#/definitions/Application"
1241
- },
1242
- propertyNames: {
1243
- description: "The unique identifier for a Microfrontend Application. Must match the `name` field of the application's `package.json`."
1244
- },
1245
- description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
1246
- },
1247
1299
  applications: {
1248
1300
  $ref: "#/definitions/ApplicationRouting",
1249
1301
  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"
1250
1302
  }
1251
1303
  },
1252
- required: [
1253
- "applications"
1254
- ],
1304
+ required: ["applications"],
1255
1305
  additionalProperties: false
1256
1306
  },
1257
1307
  Options: {
@@ -1259,11 +1309,21 @@ var schema_default = {
1259
1309
  properties: {
1260
1310
  vercel: {
1261
1311
  $ref: "#/definitions/VercelOptions",
1262
- description: "Micro-Frontends wide options for Vercel."
1312
+ description: "Microfrontends wide options for Vercel.",
1313
+ deprecated: "This is being replaced by the `disableOverrides` field below."
1314
+ },
1315
+ disableOverrides: {
1316
+ type: "boolean",
1317
+ 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."
1263
1318
  },
1264
1319
  localProxy: {
1265
1320
  $ref: "#/definitions/LocalProxyOptions",
1266
- description: "Options for local proxy."
1321
+ description: "Options for local proxy.",
1322
+ deprecated: "This is being replaced by the `localProxyPort` field below."
1323
+ },
1324
+ localProxyPort: {
1325
+ type: "number",
1326
+ description: "The port number used by the local proxy server.\n\nThe default is `3024`."
1267
1327
  }
1268
1328
  },
1269
1329
  additionalProperties: false
@@ -1271,10 +1331,6 @@ var schema_default = {
1271
1331
  VercelOptions: {
1272
1332
  type: "object",
1273
1333
  properties: {
1274
- teamSlug: {
1275
- type: "string",
1276
- description: "Team slug for the Vercel team"
1277
- },
1278
1334
  disableOverrides: {
1279
1335
  type: "boolean",
1280
1336
  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."
@@ -1292,6 +1348,15 @@ var schema_default = {
1292
1348
  },
1293
1349
  additionalProperties: false
1294
1350
  },
1351
+ ApplicationRouting: {
1352
+ type: "object",
1353
+ additionalProperties: {
1354
+ $ref: "#/definitions/Application"
1355
+ },
1356
+ propertyNames: {
1357
+ description: "The unique identifier for a Microfrontend Application. Must match the `name` field of the application's `package.json`."
1358
+ }
1359
+ },
1295
1360
  Application: {
1296
1361
  anyOf: [
1297
1362
  {
@@ -1306,18 +1371,22 @@ var schema_default = {
1306
1371
  type: "object",
1307
1372
  properties: {
1308
1373
  vercel: {
1309
- $ref: "#/definitions/Vercel"
1374
+ $ref: "#/definitions/Vercel",
1375
+ deprecated: "This is being replaced by the `projectId` field below."
1376
+ },
1377
+ projectId: {
1378
+ type: "string",
1379
+ description: "Vercel project ID"
1310
1380
  },
1311
1381
  development: {
1312
1382
  $ref: "#/definitions/Development"
1313
1383
  },
1314
1384
  production: {
1315
- $ref: "#/definitions/HostConfig"
1385
+ $ref: "#/definitions/HostConfig",
1386
+ deprecated: "This is a duplicate of the `development.fallback` field and this will be removed soon."
1316
1387
  }
1317
1388
  },
1318
- required: [
1319
- "production"
1320
- ],
1389
+ required: ["production"],
1321
1390
  additionalProperties: false
1322
1391
  },
1323
1392
  Vercel: {
@@ -1328,20 +1397,30 @@ var schema_default = {
1328
1397
  description: "Vercel project ID"
1329
1398
  }
1330
1399
  },
1331
- required: [
1332
- "projectId"
1333
- ],
1400
+ required: ["projectId"],
1334
1401
  additionalProperties: false
1335
1402
  },
1336
1403
  Development: {
1337
1404
  type: "object",
1338
1405
  properties: {
1339
1406
  local: {
1340
- $ref: "#/definitions/LocalHostConfig"
1407
+ $ref: "#/definitions/LocalHostConfig",
1408
+ deprecated: "This is being replaced by the `localPort` field below."
1409
+ },
1410
+ localPort: {
1411
+ type: "number",
1412
+ description: "The local port number that this application runs on when it is running locally. Common values include `80` for HTTP and `443` for HTTPS."
1341
1413
  },
1342
1414
  fallback: {
1343
- $ref: "#/definitions/HostConfig",
1344
- description: "Fallback for local development, could be a host config that points to any environment. If this is not provided, or the application is not running - requests to the application in local development will error."
1415
+ anyOf: [
1416
+ {
1417
+ $ref: "#/definitions/HostConfig"
1418
+ },
1419
+ {
1420
+ type: "string"
1421
+ }
1422
+ ],
1423
+ description: "Fallback for local development, could be a host config that points to any environment. If this is not provided, or the application is not running - requests to the application in local development will error.\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."
1345
1424
  },
1346
1425
  task: {
1347
1426
  type: "string",
@@ -1360,10 +1439,7 @@ var schema_default = {
1360
1439
  },
1361
1440
  protocol: {
1362
1441
  type: "string",
1363
- enum: [
1364
- "http",
1365
- "https"
1366
- ],
1442
+ enum: ["http", "https"],
1367
1443
  description: "The protocol to be used for the connection.\n- `http`: Hypertext Transfer Protocol (HTTP).\n- `https`: Secure Hypertext Transfer Protocol (HTTPS).\n\n*"
1368
1444
  },
1369
1445
  port: {
@@ -1377,10 +1453,7 @@ var schema_default = {
1377
1453
  properties: {
1378
1454
  protocol: {
1379
1455
  type: "string",
1380
- enum: [
1381
- "http",
1382
- "https"
1383
- ],
1456
+ enum: ["http", "https"],
1384
1457
  description: "The protocol to be used for the connection.\n- `http`: Hypertext Transfer Protocol (HTTP).\n- `https`: Secure Hypertext Transfer Protocol (HTTPS).\n\n*"
1385
1458
  },
1386
1459
  host: {
@@ -1392,16 +1465,19 @@ var schema_default = {
1392
1465
  description: "The port number to be used for the connection. Common values include `80` for HTTP and `443` for HTTPS."
1393
1466
  }
1394
1467
  },
1395
- required: [
1396
- "host"
1397
- ],
1468
+ required: ["host"],
1398
1469
  additionalProperties: false
1399
1470
  },
1400
1471
  ChildApplication: {
1401
1472
  type: "object",
1402
1473
  properties: {
1403
1474
  vercel: {
1404
- $ref: "#/definitions/Vercel"
1475
+ $ref: "#/definitions/Vercel",
1476
+ deprecated: "This is being replaced by the `projectId` field below."
1477
+ },
1478
+ projectId: {
1479
+ type: "string",
1480
+ description: "Vercel project ID"
1405
1481
  },
1406
1482
  development: {
1407
1483
  $ref: "#/definitions/Development"
@@ -1411,12 +1487,11 @@ var schema_default = {
1411
1487
  description: "Groups of path expressions that are routed to this application."
1412
1488
  },
1413
1489
  production: {
1414
- $ref: "#/definitions/HostConfig"
1490
+ $ref: "#/definitions/HostConfig",
1491
+ deprecated: "This is a duplicate of the `development.fallback` field and this will be removed soon."
1415
1492
  }
1416
1493
  },
1417
- required: [
1418
- "routing"
1419
- ],
1494
+ required: ["routing"],
1420
1495
  additionalProperties: false
1421
1496
  },
1422
1497
  Routing: {
@@ -1443,20 +1518,9 @@ var schema_default = {
1443
1518
  }
1444
1519
  }
1445
1520
  },
1446
- required: [
1447
- "paths"
1448
- ],
1521
+ required: ["paths"],
1449
1522
  additionalProperties: false
1450
1523
  },
1451
- ApplicationRouting: {
1452
- type: "object",
1453
- additionalProperties: {
1454
- $ref: "#/definitions/Application"
1455
- },
1456
- propertyNames: {
1457
- description: "The unique identifier for a Microfrontend Application. Must match the `name` field of the application's `package.json`."
1458
- }
1459
- },
1460
1524
  ChildConfig: {
1461
1525
  type: "object",
1462
1526
  properties: {
@@ -1470,24 +1534,12 @@ var schema_default = {
1470
1534
  options: {
1471
1535
  $ref: "#/definitions/Options"
1472
1536
  },
1473
- remotes: {
1474
- type: "object",
1475
- additionalProperties: {
1476
- $ref: "#/definitions/Application"
1477
- },
1478
- propertyNames: {
1479
- description: "The unique identifier for a Microfrontend Application. Must match the `name` field of the application's `package.json`."
1480
- },
1481
- description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
1482
- },
1483
1537
  partOf: {
1484
1538
  type: "string",
1485
1539
  description: "Applications that only serve a subset of the microfrontend routes only need to reference the name of the primary application that owns the full microfrontends configuration."
1486
1540
  }
1487
1541
  },
1488
- required: [
1489
- "partOf"
1490
- ],
1542
+ required: ["partOf"],
1491
1543
  additionalProperties: false
1492
1544
  }
1493
1545
  }
@@ -1497,6 +1549,14 @@ var schema_default = {
1497
1549
  var SCHEMA = schema_default;
1498
1550
 
1499
1551
  // src/config/microfrontends/server/validation.ts
1552
+ function filterAjvErrors(errors) {
1553
+ if (!errors) {
1554
+ return [];
1555
+ }
1556
+ return errors.filter((error) => {
1557
+ return error.keyword === "additionalProperties" || error.keyword === "required";
1558
+ });
1559
+ }
1500
1560
  function validateSchema(configString) {
1501
1561
  const parsedConfig = (0, import_jsonc_parser3.parse)(configString);
1502
1562
  const ajv = new import_ajv.Ajv();
@@ -1504,7 +1564,10 @@ function validateSchema(configString) {
1504
1564
  const isValid = validate(parsedConfig);
1505
1565
  if (!isValid) {
1506
1566
  throw new MicrofrontendError(
1507
- `Invalid config: ${ajv.errorsText(validate.errors)}`,
1567
+ `Invalid microfrontends config:
1568
+ - ${ajv.errorsText(filterAjvErrors(validate.errors), { separator: "\n - " })}
1569
+
1570
+ See https://openapi.vercel.sh/microfrontends.json for the schema.`,
1508
1571
  { type: "config", subtype: "does_not_match_schema" }
1509
1572
  );
1510
1573
  }
@@ -1644,8 +1707,8 @@ var MicrofrontendsServer = class extends Microfrontends {
1644
1707
  throw new Error("Unable to infer");
1645
1708
  } catch (e) {
1646
1709
  throw new MicrofrontendError(
1647
- "Unable to infer microfrontends configuration",
1648
- { type: "config", subtype: "inference_failed" }
1710
+ "Unable to locate and parse microfrontends configuration",
1711
+ { cause: e, type: "config", subtype: "inference_failed" }
1649
1712
  );
1650
1713
  }
1651
1714
  }
@@ -1721,7 +1784,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1721
1784
  const [defaultApplication] = Object.entries(validatedConfig.applications).filter(([, app]) => isDefaultApp(app)).map(([name]) => name);
1722
1785
  if (!defaultApplication) {
1723
1786
  throw new MicrofrontendError(
1724
- `No default application found. At least one application needs to be the default by omitting routing.`,
1787
+ "No default application found. At least one application needs to be the default by omitting routing.",
1725
1788
  { type: "config", subtype: "no_default_application" }
1726
1789
  );
1727
1790
  }
@@ -1759,13 +1822,13 @@ var ProxyRequestRouter = class {
1759
1822
  getApplicationTarget(application) {
1760
1823
  const useDev = this.localApps.includes(application.name);
1761
1824
  let applicationName = application.name;
1762
- let host = useDev ? application.development.local : application.production;
1825
+ let host = useDev ? application.development.local : application.fallback;
1763
1826
  if (application.overrides?.environment?.host) {
1764
1827
  host = application.overrides.environment;
1765
1828
  }
1766
1829
  if (!host) {
1767
1830
  const defaultApp = this.config.getDefaultApplication();
1768
- host = defaultApp.production;
1831
+ host = defaultApp.fallback;
1769
1832
  applicationName = defaultApp.name;
1770
1833
  }
1771
1834
  const protocol = host.protocol;
@@ -2106,7 +2169,7 @@ function loadConfig({
2106
2169
  return void 0;
2107
2170
  }
2108
2171
  const app = config.config.getApplication(appName);
2109
- const port = app.development.local.port;
2172
+ const port = app.development.local.port ?? (app.development.local.protocol === "https" ? 443 : 80);
2110
2173
  return { port };
2111
2174
  }
2112
2175