@vercel/microfrontends 2.0.0 → 2.1.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 (46) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -5
  3. package/dist/bin/cli.cjs +226 -79
  4. package/dist/config.cjs +5 -4
  5. package/dist/config.cjs.map +1 -1
  6. package/dist/config.js +5 -4
  7. package/dist/config.js.map +1 -1
  8. package/dist/experimental/sveltekit.cjs +51 -20
  9. package/dist/experimental/sveltekit.cjs.map +1 -1
  10. package/dist/experimental/sveltekit.js +51 -20
  11. package/dist/experimental/sveltekit.js.map +1 -1
  12. package/dist/experimental/vite.cjs +51 -20
  13. package/dist/experimental/vite.cjs.map +1 -1
  14. package/dist/experimental/vite.js +51 -20
  15. package/dist/experimental/vite.js.map +1 -1
  16. package/dist/microfrontends/server.cjs +51 -20
  17. package/dist/microfrontends/server.cjs.map +1 -1
  18. package/dist/microfrontends/server.js +51 -20
  19. package/dist/microfrontends/server.js.map +1 -1
  20. package/dist/microfrontends/utils.cjs +32 -7
  21. package/dist/microfrontends/utils.cjs.map +1 -1
  22. package/dist/microfrontends/utils.d.ts +8 -2
  23. package/dist/microfrontends/utils.js +31 -7
  24. package/dist/microfrontends/utils.js.map +1 -1
  25. package/dist/next/client.cjs +1 -1
  26. package/dist/next/client.cjs.map +1 -1
  27. package/dist/next/client.d.ts +15 -1
  28. package/dist/next/client.js +1 -1
  29. package/dist/next/client.js.map +1 -1
  30. package/dist/next/config.cjs +62 -20
  31. package/dist/next/config.cjs.map +1 -1
  32. package/dist/next/config.js +62 -20
  33. package/dist/next/config.js.map +1 -1
  34. package/dist/next/middleware.cjs +5 -4
  35. package/dist/next/middleware.cjs.map +1 -1
  36. package/dist/next/middleware.js +5 -4
  37. package/dist/next/middleware.js.map +1 -1
  38. package/dist/next/testing.cjs +5 -4
  39. package/dist/next/testing.cjs.map +1 -1
  40. package/dist/next/testing.js +5 -4
  41. package/dist/next/testing.js.map +1 -1
  42. package/dist/utils/mfe-port.cjs +66 -40
  43. package/dist/utils/mfe-port.cjs.map +1 -1
  44. package/dist/utils/mfe-port.js +66 -40
  45. package/dist/utils/mfe-port.js.map +1 -1
  46. package/package.json +4 -4
@@ -204,22 +204,38 @@ import { readFileSync } from "node:fs";
204
204
  import { parse } from "jsonc-parser";
205
205
  import fg from "fast-glob";
206
206
 
207
- // src/config/constants.ts
208
- var CONFIGURATION_FILENAMES = [
207
+ // src/config/microfrontends/utils/get-config-file-name.ts
208
+ var DEFAULT_CONFIGURATION_FILENAMES = [
209
209
  "microfrontends.jsonc",
210
210
  "microfrontends.json"
211
211
  ];
212
+ function getPossibleConfigurationFilenames({
213
+ customConfigFilename
214
+ }) {
215
+ if (customConfigFilename) {
216
+ if (!customConfigFilename.endsWith(".json") && !customConfigFilename.endsWith(".jsonc")) {
217
+ throw new Error(
218
+ `The VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable must end with '.json' or '.jsonc'. Received: ${customConfigFilename}`
219
+ );
220
+ }
221
+ return Array.from(
222
+ /* @__PURE__ */ new Set([customConfigFilename, ...DEFAULT_CONFIGURATION_FILENAMES])
223
+ );
224
+ }
225
+ return DEFAULT_CONFIGURATION_FILENAMES;
226
+ }
212
227
 
213
228
  // src/config/microfrontends/utils/infer-microfrontends-location.ts
214
229
  var configCache = {};
215
230
  function findPackageWithMicrofrontendsConfig({
216
231
  repositoryRoot,
217
- applicationContext
232
+ applicationContext,
233
+ customConfigFilename
218
234
  }) {
219
235
  const applicationName = applicationContext.name;
220
236
  try {
221
237
  const microfrontendsJsonPaths = fg.globSync(
222
- `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
238
+ `**/{${getPossibleConfigurationFilenames({ customConfigFilename }).join(",")}}`,
223
239
  {
224
240
  cwd: repositoryRoot,
225
241
  absolute: true,
@@ -275,6 +291,8 @@ Names of applications in \`microfrontends.json\` must match the Vercel Project n
275
291
 
276
292
  If your Vercel Microfrontends configuration is not in this repository, you can use the Vercel CLI to pull the Vercel Microfrontends configuration using the "vercel microfrontends pull" command, or you can specify the path manually using the VC_MICROFRONTENDS_CONFIG environment variable.
277
293
 
294
+ If your Vercel Microfrontends configuration has a custom name, ensure the VC_MICROFRONTENDS_CONFIG_FILE_NAME environment variable is set, you can pull the vercel project environment variables using the "vercel env pull" command.
295
+
278
296
  If you suspect this is thrown in error, please reach out to the Vercel team.`,
279
297
  { type: "config", subtype: "inference_failed" }
280
298
  );
@@ -289,7 +307,7 @@ If you suspect this is thrown in error, please reach out to the Vercel team.`,
289
307
  }
290
308
  }
291
309
  function inferMicrofrontendsLocation(opts) {
292
- const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}`;
310
+ const cacheKey = `${opts.repositoryRoot}-${opts.applicationContext.name}${opts.customConfigFilename ? `-${opts.customConfigFilename}` : ""}`;
293
311
  if (configCache[cacheKey]) {
294
312
  return configCache[cacheKey];
295
313
  }
@@ -355,8 +373,13 @@ function findPackageRoot(startDir) {
355
373
  // src/config/microfrontends/utils/find-config.ts
356
374
  import fs4 from "node:fs";
357
375
  import { join } from "node:path";
358
- function findConfig({ dir }) {
359
- for (const filename of CONFIGURATION_FILENAMES) {
376
+ function findConfig({
377
+ dir,
378
+ customConfigFilename
379
+ }) {
380
+ for (const filename of getPossibleConfigurationFilenames({
381
+ customConfigFilename
382
+ })) {
360
383
  const maybeConfig = join(dir, filename);
361
384
  if (fs4.existsSync(maybeConfig)) {
362
385
  return maybeConfig;
@@ -423,7 +446,7 @@ var MicrofrontendConfigClient = class {
423
446
  static fromEnv(config) {
424
447
  if (!config) {
425
448
  throw new Error(
426
- "Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`?"
449
+ "Could not construct MicrofrontendConfigClient: configuration is empty or undefined. Did you set up your application with `withMicrofrontends`? Is the local proxy running and this application is being accessed via the proxy port? See https://vercel.com/docs/microfrontends/local-development#setting-up-microfrontends-proxy"
427
450
  );
428
451
  }
429
452
  return new MicrofrontendConfigClient(JSON.parse(config));
@@ -563,10 +586,11 @@ function validatePathExpression(path6) {
563
586
  }
564
587
  if (token.pattern !== PATH_DEFAULT_PATTERN && // Allows (a|b|c) and ((?!a|b|c).*) regex
565
588
  // Only limited regex is supported for now, due to performance considerations
566
- !/^(?<allowed>[\w]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w]+(?:\|[^:|()]+)*)\)\.\*$/.test(
567
- token.pattern
589
+ // Allows all letters, numbers, and hyphens. Other characters must be escaped.
590
+ !/^(?<allowed>[\w-~]+(?:\|[^:|()]+)+)$|^\(\?!(?<disallowed>[\w-~]+(?:\|[^:|()]+)*)\)\.\*$/.test(
591
+ token.pattern.replace(/\\./g, "")
568
592
  )) {
569
- return `Path ${path6} cannot use unsupported regular expression wildcard`;
593
+ return `Path ${path6} cannot use unsupported regular expression wildcard. If the path includes special characters, they must be escaped with backslash (e.g. '\\(')`;
570
594
  }
571
595
  if (token.modifier && i !== tokens.length - 1) {
572
596
  return `Modifier ${token.modifier} is not allowed on wildcard :${token.name} in ${path6}. Modifiers are only allowed in the last path component`;
@@ -1458,7 +1482,11 @@ var MicrofrontendsServer = class {
1458
1482
  appName,
1459
1483
  packageRoot
1460
1484
  });
1461
- const maybeConfig = findConfig({ dir: packageRoot });
1485
+ const customConfigFilename = process.env.VC_MICROFRONTENDS_CONFIG_FILE_NAME;
1486
+ const maybeConfig = findConfig({
1487
+ dir: packageRoot,
1488
+ customConfigFilename
1489
+ });
1462
1490
  if (maybeConfig) {
1463
1491
  return MicrofrontendsServer.fromFile({
1464
1492
  filePath: maybeConfig,
@@ -1467,11 +1495,9 @@ var MicrofrontendsServer = class {
1467
1495
  }
1468
1496
  const repositoryRoot = findRepositoryRoot();
1469
1497
  const isMonorepo2 = isMonorepo({ repositoryRoot });
1470
- if (typeof process.env.VC_MICROFRONTENDS_CONFIG === "string") {
1471
- const maybeConfigFromEnv = resolve(
1472
- packageRoot,
1473
- process.env.VC_MICROFRONTENDS_CONFIG
1474
- );
1498
+ const configFromEnv = process.env.VC_MICROFRONTENDS_CONFIG;
1499
+ if (typeof configFromEnv === "string") {
1500
+ const maybeConfigFromEnv = resolve(packageRoot, configFromEnv);
1475
1501
  if (maybeConfigFromEnv) {
1476
1502
  return MicrofrontendsServer.fromFile({
1477
1503
  filePath: maybeConfigFromEnv,
@@ -1480,7 +1506,8 @@ var MicrofrontendsServer = class {
1480
1506
  }
1481
1507
  } else {
1482
1508
  const maybeConfigFromVercel = findConfig({
1483
- dir: join2(packageRoot, ".vercel")
1509
+ dir: join2(packageRoot, ".vercel"),
1510
+ customConfigFilename
1484
1511
  });
1485
1512
  if (maybeConfigFromVercel) {
1486
1513
  return MicrofrontendsServer.fromFile({
@@ -1491,9 +1518,13 @@ var MicrofrontendsServer = class {
1491
1518
  if (isMonorepo2) {
1492
1519
  const defaultPackage = inferMicrofrontendsLocation({
1493
1520
  repositoryRoot,
1494
- applicationContext
1521
+ applicationContext,
1522
+ customConfigFilename
1523
+ });
1524
+ const maybeConfigFromDefault = findConfig({
1525
+ dir: defaultPackage,
1526
+ customConfigFilename
1495
1527
  });
1496
- const maybeConfigFromDefault = findConfig({ dir: defaultPackage });
1497
1528
  if (maybeConfigFromDefault) {
1498
1529
  return MicrofrontendsServer.fromFile({
1499
1530
  filePath: maybeConfigFromDefault,
@@ -1732,6 +1763,14 @@ function transform6(args) {
1732
1763
  pathname: "/.well-known/vercel/flags"
1733
1764
  }
1734
1765
  });
1766
+ rewrites.set(
1767
+ `/${app.getAssetPrefix()}/.well-known/vercel/rate-limit-api/:path*`,
1768
+ {
1769
+ destination: {
1770
+ pathname: "/.well-known/vercel/rate-limit-api/:path*"
1771
+ }
1772
+ }
1773
+ );
1735
1774
  rewrites.set(`/${app.getAssetPrefix()}/_vercel/:path*`, {
1736
1775
  destination: {
1737
1776
  pathname: "/_vercel/:path*"
@@ -1919,6 +1958,9 @@ function setEnvironment({
1919
1958
  removeFlaggedPaths: true
1920
1959
  }).serialize()
1921
1960
  ),
1961
+ ...app.getAssetPrefix() ? {
1962
+ NEXT_PUBLIC_VERCEL_FIREWALL_PATH_PREFIX: `/${app.getAssetPrefix()}`
1963
+ } : {},
1922
1964
  ...process.env.ROUTE_OBSERVABILITY_TO_THIS_PROJECT && app.getAssetPrefix() ? {
1923
1965
  NEXT_PUBLIC_VERCEL_OBSERVABILITY_BASEPATH: `/${app.getAssetPrefix()}/_vercel`
1924
1966
  } : {}