@vercel/microfrontends 1.1.1-canary.2 → 1.1.1-canary.4

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 (64) hide show
  1. package/dist/bin/cli.cjs +303 -512
  2. package/dist/config.cjs +43 -71
  3. package/dist/config.cjs.map +1 -1
  4. package/dist/config.d.ts +153 -4
  5. package/dist/config.js +43 -71
  6. package/dist/config.js.map +1 -1
  7. package/dist/experimental/sveltekit.cjs +296 -489
  8. package/dist/experimental/sveltekit.cjs.map +1 -1
  9. package/dist/experimental/sveltekit.js +286 -479
  10. package/dist/experimental/sveltekit.js.map +1 -1
  11. package/dist/experimental/vite.cjs +326 -511
  12. package/dist/experimental/vite.cjs.map +1 -1
  13. package/dist/experimental/vite.js +312 -497
  14. package/dist/experimental/vite.js.map +1 -1
  15. package/dist/microfrontends/server.cjs +295 -485
  16. package/dist/microfrontends/server.cjs.map +1 -1
  17. package/dist/microfrontends/server.d.ts +14 -20
  18. package/dist/microfrontends/server.js +285 -475
  19. package/dist/microfrontends/server.js.map +1 -1
  20. package/dist/next/config.cjs +297 -498
  21. package/dist/next/config.cjs.map +1 -1
  22. package/dist/next/config.js +287 -488
  23. package/dist/next/config.js.map +1 -1
  24. package/dist/next/endpoints.cjs +2 -0
  25. package/dist/next/endpoints.cjs.map +1 -1
  26. package/dist/next/endpoints.d.ts +13 -3
  27. package/dist/next/endpoints.js +1 -0
  28. package/dist/next/endpoints.js.map +1 -1
  29. package/dist/next/middleware.cjs +58 -171
  30. package/dist/next/middleware.cjs.map +1 -1
  31. package/dist/next/middleware.d.ts +2 -4
  32. package/dist/next/middleware.js +58 -171
  33. package/dist/next/middleware.js.map +1 -1
  34. package/dist/next/testing.cjs +44 -73
  35. package/dist/next/testing.cjs.map +1 -1
  36. package/dist/next/testing.d.ts +4 -4
  37. package/dist/next/testing.js +44 -73
  38. package/dist/next/testing.js.map +1 -1
  39. package/dist/overrides.d.ts +3 -3
  40. package/dist/schema.cjs +2 -9
  41. package/dist/schema.cjs.map +1 -1
  42. package/dist/schema.d.ts +3 -4
  43. package/dist/schema.js +1 -7
  44. package/dist/schema.js.map +1 -1
  45. package/dist/{types-6ee19ccc.d.ts → types-54064641.d.ts} +2 -13
  46. package/dist/{types-73527280.d.ts → types-a4add5ab.d.ts} +1 -1
  47. package/dist/{types-74e3336c.d.ts → types-f1260e44.d.ts} +1 -1
  48. package/dist/utils/mfe-port.cjs +300 -492
  49. package/dist/utils/mfe-port.cjs.map +1 -1
  50. package/dist/utils/mfe-port.js +286 -478
  51. package/dist/utils/mfe-port.js.map +1 -1
  52. package/dist/validation.cjs +49 -37
  53. package/dist/validation.cjs.map +1 -1
  54. package/dist/validation.d.ts +1 -1
  55. package/dist/validation.js +49 -37
  56. package/dist/validation.js.map +1 -1
  57. package/package.json +2 -9
  58. package/schema/schema.json +0 -33
  59. package/dist/index-7e69650e.d.ts +0 -165
  60. package/dist/microfrontends.cjs +0 -962
  61. package/dist/microfrontends.cjs.map +0 -1
  62. package/dist/microfrontends.d.ts +0 -45
  63. package/dist/microfrontends.js +0 -935
  64. package/dist/microfrontends.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  // src/config/microfrontends/server/index.ts
2
2
  import fs6 from "node:fs";
3
- import { dirname as dirname3 } from "node:path";
3
+ import { dirname as dirname2 } from "node:path";
4
4
 
5
5
  // src/config/overrides/constants.ts
6
6
  var OVERRIDES_COOKIE_PREFIX = "vercel-micro-frontends-override";
@@ -139,19 +139,177 @@ function getConfigStringFromEnv() {
139
139
  return config;
140
140
  }
141
141
 
142
- // src/config/microfrontends-config/isomorphic/index.ts
142
+ // src/config/schema/utils/is-default-app.ts
143
+ function isDefaultApp(a) {
144
+ return !("routing" in a);
145
+ }
146
+
147
+ // src/config/microfrontends/utils/find-repository-root.ts
148
+ import fs from "node:fs";
149
+ import path from "node:path";
150
+ var GIT_DIRECTORY = ".git";
151
+ function hasGitDirectory(dir) {
152
+ const gitPath = path.join(dir, GIT_DIRECTORY);
153
+ return fs.existsSync(gitPath) && fs.statSync(gitPath).isDirectory();
154
+ }
155
+ function hasPnpmWorkspaces(dir) {
156
+ return fs.existsSync(path.join(dir, "pnpm-workspace.yaml"));
157
+ }
158
+ function findRepositoryRoot(startDir) {
159
+ if (process.env.NX_WORKSPACE_ROOT) {
160
+ return process.env.NX_WORKSPACE_ROOT;
161
+ }
162
+ let currentDir = startDir || process.cwd();
163
+ while (currentDir !== path.parse(currentDir).root) {
164
+ if (hasGitDirectory(currentDir) || hasPnpmWorkspaces(currentDir)) {
165
+ return currentDir;
166
+ }
167
+ currentDir = path.dirname(currentDir);
168
+ }
169
+ throw new Error(
170
+ "Repository root not found. Specify the root of the repository with the `repository.root` option."
171
+ );
172
+ }
173
+
174
+ // src/config/microfrontends/utils/find-default-package.ts
175
+ import { dirname } from "node:path";
176
+ import { readFileSync } from "node:fs";
143
177
  import { parse } from "jsonc-parser";
178
+ import fg from "fast-glob";
144
179
 
145
- // src/config/schema/utils/is-main-config.ts
146
- function isMainConfig(c) {
147
- return !("partOf" in c);
180
+ // src/config/constants.ts
181
+ var CONFIGURATION_FILENAMES = [
182
+ "microfrontends.jsonc",
183
+ "microfrontends.json"
184
+ ];
185
+
186
+ // src/config/microfrontends/utils/find-default-package.ts
187
+ var configCache = {};
188
+ function findDefaultMicrofrontendsPackages({
189
+ repositoryRoot,
190
+ applicationName
191
+ }) {
192
+ try {
193
+ const microfrontendsJsonPaths = fg.globSync(
194
+ `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
195
+ {
196
+ cwd: repositoryRoot,
197
+ absolute: true,
198
+ onlyFiles: true,
199
+ followSymbolicLinks: false,
200
+ ignore: ["**/node_modules/**", "**/.git/**"]
201
+ }
202
+ );
203
+ const matchingPaths = [];
204
+ for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
205
+ try {
206
+ const microfrontendsJsonContent = readFileSync(
207
+ microfrontendsJsonPath,
208
+ "utf-8"
209
+ );
210
+ const microfrontendsJson = parse(microfrontendsJsonContent);
211
+ if (microfrontendsJson.applications[applicationName]) {
212
+ matchingPaths.push(microfrontendsJsonPath);
213
+ }
214
+ } catch (error) {
215
+ }
216
+ }
217
+ if (matchingPaths.length > 1) {
218
+ throw new Error(
219
+ `Found multiple default applications referencing "${applicationName}" in the repository, but only one is allowed.
220
+ ${matchingPaths.join("\n \u2022 ")}`
221
+ );
222
+ }
223
+ if (matchingPaths.length === 0) {
224
+ throw new Error(
225
+ `Could not find default application with "applications.${applicationName}"`
226
+ );
227
+ }
228
+ const [packageJsonPath] = matchingPaths;
229
+ return dirname(packageJsonPath);
230
+ } catch (error) {
231
+ return null;
232
+ }
233
+ }
234
+ function findDefaultMicrofrontendsPackage(opts) {
235
+ const cacheKey = `${opts.repositoryRoot}-${opts.applicationName}`;
236
+ if (configCache[cacheKey]) {
237
+ return configCache[cacheKey];
238
+ }
239
+ const result = findDefaultMicrofrontendsPackages(opts);
240
+ if (!result) {
241
+ throw new Error(
242
+ "Error trying to resolve the main microfrontends configuration"
243
+ );
244
+ }
245
+ configCache[cacheKey] = result;
246
+ return result;
148
247
  }
149
248
 
150
- // src/config/schema/utils/is-default-app.ts
151
- function isDefaultApp(a) {
152
- return !("routing" in a);
249
+ // src/config/microfrontends/utils/is-monorepo.ts
250
+ import fs2 from "node:fs";
251
+ import path2 from "node:path";
252
+ function isMonorepo({
253
+ repositoryRoot
254
+ }) {
255
+ try {
256
+ if (fs2.existsSync(path2.join(repositoryRoot, "pnpm-workspace.yaml"))) {
257
+ return true;
258
+ }
259
+ if (fs2.existsSync(path2.join(repositoryRoot, "vlt-workspaces.json"))) {
260
+ return true;
261
+ }
262
+ if (process.env.NX_WORKSPACE_ROOT === path2.resolve(repositoryRoot)) {
263
+ return true;
264
+ }
265
+ const packageJsonPath = path2.join(repositoryRoot, "package.json");
266
+ if (!fs2.existsSync(packageJsonPath)) {
267
+ return false;
268
+ }
269
+ const packageJson = JSON.parse(
270
+ fs2.readFileSync(packageJsonPath, "utf-8")
271
+ );
272
+ return packageJson.workspaces !== void 0;
273
+ } catch (error) {
274
+ console.error("Error determining if repository is a monorepo", error);
275
+ return false;
276
+ }
153
277
  }
154
278
 
279
+ // src/config/microfrontends/utils/find-package-root.ts
280
+ import fs3 from "node:fs";
281
+ import path3 from "node:path";
282
+ var PACKAGE_JSON = "package.json";
283
+ function findPackageRoot(startDir) {
284
+ let currentDir = startDir || process.cwd();
285
+ while (currentDir !== path3.parse(currentDir).root) {
286
+ const pkgJsonPath = path3.join(currentDir, PACKAGE_JSON);
287
+ if (fs3.existsSync(pkgJsonPath)) {
288
+ return currentDir;
289
+ }
290
+ currentDir = path3.dirname(currentDir);
291
+ }
292
+ throw new Error(
293
+ "Package root not found. Specify the root of the package with the `package.root` option."
294
+ );
295
+ }
296
+
297
+ // src/config/microfrontends/utils/find-config.ts
298
+ import fs4 from "node:fs";
299
+ import { join } from "node:path";
300
+ function findConfig({ dir }) {
301
+ for (const filename of CONFIGURATION_FILENAMES) {
302
+ const maybeConfig = join(dir, filename);
303
+ if (fs4.existsSync(maybeConfig)) {
304
+ return maybeConfig;
305
+ }
306
+ }
307
+ return null;
308
+ }
309
+
310
+ // src/config/microfrontends-config/isomorphic/index.ts
311
+ import { parse as parse2 } from "jsonc-parser";
312
+
155
313
  // src/config/microfrontends-config/client/index.ts
156
314
  import { pathToRegexp } from "path-to-regexp";
157
315
  var MicrofrontendConfigClient = class {
@@ -220,6 +378,10 @@ var MicrofrontendConfigClient = class {
220
378
 
221
379
  // src/config/microfrontends-config/isomorphic/validation.ts
222
380
  import { pathToRegexp as pathToRegexp2, parse as parsePathRegexp } from "path-to-regexp";
381
+ var LIST_FORMATTER = new Intl.ListFormat("en", {
382
+ style: "long",
383
+ type: "conjunction"
384
+ });
223
385
  var validateConfigPaths = (applicationConfigsById) => {
224
386
  if (!applicationConfigsById) {
225
387
  return;
@@ -352,15 +514,15 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
352
514
  if (!applicationConfigsById) {
353
515
  return;
354
516
  }
355
- const applicationsWithRouting = Object.entries(applicationConfigsById).filter(
356
- ([, app]) => !isDefaultApp(app)
357
- );
358
- const applicationsWithRoutingNames = applicationsWithRouting.map(
359
- ([key]) => key
517
+ const applicationsWithoutRouting = Object.entries(
518
+ applicationConfigsById
519
+ ).filter(([, app]) => isDefaultApp(app));
520
+ const numApplicationsWithoutRouting = applicationsWithoutRouting.reduce(
521
+ (acc) => {
522
+ return acc + 1;
523
+ },
524
+ 0
360
525
  );
361
- const numApplications = Object.keys(applicationConfigsById).length;
362
- const numApplicationsWithRouting = applicationsWithRoutingNames.length;
363
- const numApplicationsWithoutRouting = numApplications - numApplicationsWithRouting;
364
526
  if (numApplicationsWithoutRouting === 0) {
365
527
  throw new MicrofrontendError(
366
528
  "No default application found. At least one application needs to be the default by omitting routing.",
@@ -368,8 +530,11 @@ var validateConfigDefaultApplication = (applicationConfigsById) => {
368
530
  );
369
531
  }
370
532
  if (numApplicationsWithoutRouting > 1) {
533
+ const applicationNamesMissingRouting = applicationsWithoutRouting.map(
534
+ ([name]) => name
535
+ );
371
536
  throw new MicrofrontendError(
372
- `Only one application can omit "routing". Found ${applicationsWithRoutingNames.length - Object.keys(applicationConfigsById).length > 1}.`,
537
+ `All applications except for the default app must contain the "routing" field. Applications that are missing routing: ${LIST_FORMATTER.format(applicationNamesMissingRouting)}.`,
373
538
  { type: "config", subtype: "multiple_default_applications" }
374
539
  );
375
540
  }
@@ -680,42 +845,28 @@ var MicrofrontendConfigIsomorphic = class {
680
845
  constructor({
681
846
  config,
682
847
  overrides,
683
- meta,
684
848
  opts
685
849
  }) {
686
850
  this.childApplications = {};
687
851
  MicrofrontendConfigIsomorphic.validate(config, opts);
688
852
  const disableOverrides = config.options?.disableOverrides ?? config.options?.vercel?.disableOverrides ?? false;
689
853
  this.overrides = overrides && !disableOverrides ? overrides : void 0;
690
- this.isMainConfig = isMainConfig(config);
691
- if (isMainConfig(config)) {
692
- for (const [appId, appConfig] of Object.entries(config.applications)) {
693
- const appOverrides = !disableOverrides ? this.overrides?.applications[appId] : void 0;
694
- if (isDefaultApp(appConfig)) {
695
- this.defaultApplication = new DefaultApplication(appId, {
696
- app: appConfig,
697
- overrides: appOverrides
698
- });
699
- } else {
700
- this.childApplications[appId] = new ChildApplication(appId, {
701
- app: appConfig,
702
- overrides: appOverrides
703
- });
704
- }
705
- }
706
- } else {
707
- this.partOf = config.partOf;
708
- const appOverrides = !disableOverrides ? this.overrides?.applications[meta.fromApp] : void 0;
709
- this.childApplications[meta.fromApp] = new ChildApplication(
710
- meta.fromApp,
711
- {
712
- // we don't know routing because we're not in the main config
713
- app: { routing: [] },
854
+ let defaultApplication;
855
+ for (const [appId, appConfig] of Object.entries(config.applications)) {
856
+ const appOverrides = !disableOverrides ? this.overrides?.applications[appId] : void 0;
857
+ if (isDefaultApp(appConfig)) {
858
+ defaultApplication = new DefaultApplication(appId, {
859
+ app: appConfig,
714
860
  overrides: appOverrides
715
- }
716
- );
861
+ });
862
+ } else {
863
+ this.childApplications[appId] = new ChildApplication(appId, {
864
+ app: appConfig,
865
+ overrides: appOverrides
866
+ });
867
+ }
717
868
  }
718
- if (isMainConfig(config) && !this.defaultApplication) {
869
+ if (!defaultApplication) {
719
870
  throw new MicrofrontendError(
720
871
  "Could not find default application in microfrontends configuration",
721
872
  {
@@ -724,34 +875,30 @@ var MicrofrontendConfigIsomorphic = class {
724
875
  }
725
876
  );
726
877
  }
878
+ this.defaultApplication = defaultApplication;
727
879
  this.config = config;
728
880
  this.options = config.options;
729
881
  this.serialized = {
730
882
  config,
731
- overrides,
732
- meta
883
+ overrides
733
884
  };
734
885
  }
735
886
  static validate(config, opts) {
736
887
  const skipValidation = opts?.skipValidation ?? [];
737
- const c = typeof config === "string" ? parse(config) : config;
738
- if (isMainConfig(c)) {
739
- validateConfigPaths(c.applications);
740
- validateConfigDefaultApplication(c.applications);
741
- if (!skipValidation.includes("deprecatedFields")) {
742
- validateDeprecatedFields(c);
743
- }
888
+ const c = typeof config === "string" ? parse2(config) : config;
889
+ validateConfigPaths(c.applications);
890
+ validateConfigDefaultApplication(c.applications);
891
+ if (!skipValidation.includes("deprecatedFields")) {
892
+ validateDeprecatedFields(c);
744
893
  }
745
894
  return c;
746
895
  }
747
896
  static fromEnv({
748
- meta,
749
897
  cookies
750
898
  }) {
751
899
  return new MicrofrontendConfigIsomorphic({
752
- config: parse(getConfigStringFromEnv()),
753
- overrides: parseOverrides(cookies ?? []),
754
- meta
900
+ config: parse2(getConfigStringFromEnv()),
901
+ overrides: parseOverrides(cookies ?? [])
755
902
  });
756
903
  }
757
904
  isOverridesDisabled() {
@@ -776,7 +923,7 @@ var MicrofrontendConfigIsomorphic = class {
776
923
  ].filter(Boolean);
777
924
  }
778
925
  getApplication(name) {
779
- if (this.defaultApplication?.name === name || this.defaultApplication?.packageName === name) {
926
+ if (this.defaultApplication.name === name || this.defaultApplication.packageName === name) {
780
927
  return this.defaultApplication;
781
928
  }
782
929
  const app = this.childApplications[name] || Object.values(this.childApplications).find(
@@ -794,7 +941,7 @@ var MicrofrontendConfigIsomorphic = class {
794
941
  return app;
795
942
  }
796
943
  getApplicationByProjectId(projectId) {
797
- if (this.defaultApplication?.projectId === projectId) {
944
+ if (this.defaultApplication.projectId === projectId) {
798
945
  return this.defaultApplication;
799
946
  }
800
947
  return Object.values(this.childApplications).find(
@@ -802,19 +949,9 @@ var MicrofrontendConfigIsomorphic = class {
802
949
  );
803
950
  }
804
951
  /**
805
- * Returns the default application. This can throw if the default application
806
- * is undefined ( )
952
+ * Returns the default application.
807
953
  */
808
954
  getDefaultApplication() {
809
- if (!this.defaultApplication) {
810
- throw new MicrofrontendError(
811
- "Could not find default application in microfrontends configuration",
812
- {
813
- type: "application",
814
- subtype: "not_found"
815
- }
816
- );
817
- }
818
955
  return this.defaultApplication;
819
956
  }
820
957
  /**
@@ -841,11 +978,9 @@ var MicrofrontendConfigIsomorphic = class {
841
978
  }
842
979
  ])
843
980
  );
844
- if (this.defaultApplication) {
845
- applications[this.defaultApplication.name] = {
846
- default: true
847
- };
848
- }
981
+ applications[this.defaultApplication.name] = {
982
+ default: true
983
+ };
849
984
  return new MicrofrontendConfigClient({
850
985
  applications
851
986
  });
@@ -855,298 +990,6 @@ var MicrofrontendConfigIsomorphic = class {
855
990
  }
856
991
  };
857
992
 
858
- // src/config/microfrontends-config/isomorphic/child.ts
859
- var MicrofrontendChildConfig = class extends MicrofrontendConfigIsomorphic {
860
- constructor({
861
- config,
862
- overrides,
863
- meta
864
- }) {
865
- super({ config, overrides, meta });
866
- this.isMainConfig = false;
867
- this.partOf = config.partOf;
868
- }
869
- };
870
-
871
- // src/config/microfrontends-config/isomorphic/main.ts
872
- var MicrofrontendMainConfig = class extends MicrofrontendConfigIsomorphic {
873
- constructor({
874
- config,
875
- overrides,
876
- meta
877
- }) {
878
- super({ config, overrides, meta });
879
- this.isMainConfig = true;
880
- const disableOverrides = config.options?.disableOverrides ?? config.options?.vercel?.disableOverrides ?? false;
881
- let defaultApplication;
882
- for (const [appId, appConfig] of Object.entries(config.applications)) {
883
- const appOverrides = !disableOverrides ? this.overrides?.applications[appId] : void 0;
884
- if (isDefaultApp(appConfig)) {
885
- defaultApplication = new DefaultApplication(appId, {
886
- app: appConfig,
887
- overrides: appOverrides
888
- });
889
- } else {
890
- this.childApplications[appId] = new ChildApplication(appId, {
891
- app: appConfig,
892
- overrides: appOverrides
893
- });
894
- }
895
- }
896
- if (!defaultApplication) {
897
- throw new MicrofrontendError(
898
- "Could not find default application in microfrontends configuration",
899
- {
900
- type: "application",
901
- subtype: "not_found"
902
- }
903
- );
904
- }
905
- this.defaultApplication = defaultApplication;
906
- }
907
- };
908
-
909
- // src/config/microfrontends/isomorphic/index.ts
910
- var Microfrontends = class {
911
- constructor({
912
- config,
913
- overrides,
914
- meta
915
- }) {
916
- if (isMainConfig(config)) {
917
- this.config = new MicrofrontendMainConfig({ config, overrides, meta });
918
- } else {
919
- this.config = new MicrofrontendChildConfig({ config, overrides, meta });
920
- }
921
- }
922
- isChildConfig() {
923
- return this.config instanceof MicrofrontendChildConfig;
924
- }
925
- static fromEnv({
926
- cookies,
927
- meta
928
- }) {
929
- const config = MicrofrontendConfigIsomorphic.fromEnv({
930
- cookies,
931
- meta
932
- });
933
- return new Microfrontends(config.serialize());
934
- }
935
- };
936
-
937
- // src/config/microfrontends/utils/find-repository-root.ts
938
- import fs from "node:fs";
939
- import path from "node:path";
940
- var GIT_DIRECTORY = ".git";
941
- function findRepositoryRoot(startDir) {
942
- if (process.env.NX_WORKSPACE_ROOT) {
943
- return process.env.NX_WORKSPACE_ROOT;
944
- }
945
- let currentDir = startDir || process.cwd();
946
- while (currentDir !== path.parse(currentDir).root) {
947
- const gitPath = path.join(currentDir, GIT_DIRECTORY);
948
- if (fs.existsSync(gitPath) && fs.statSync(gitPath).isDirectory()) {
949
- return currentDir;
950
- }
951
- currentDir = path.dirname(currentDir);
952
- }
953
- throw new Error(
954
- "Repository root not found. Specify the root of the repository with the `repository.root` option."
955
- );
956
- }
957
-
958
- // src/config/microfrontends/utils/find-package-path.ts
959
- import { dirname } from "node:path";
960
- import { readFileSync } from "node:fs";
961
- import fg from "fast-glob";
962
- var configCache = {};
963
- function findPackagePathWithGlob({
964
- repositoryRoot,
965
- name
966
- }) {
967
- try {
968
- const packageJsonPaths = fg.globSync("**/package.json", {
969
- cwd: repositoryRoot,
970
- absolute: true,
971
- onlyFiles: true,
972
- followSymbolicLinks: false,
973
- ignore: ["**/node_modules/**", "**/.git/**"]
974
- });
975
- const matchingPaths = [];
976
- for (const packageJsonPath2 of packageJsonPaths) {
977
- const packageJsonContent = readFileSync(packageJsonPath2, "utf-8");
978
- const packageJson = JSON.parse(packageJsonContent);
979
- if (packageJson.name === name) {
980
- matchingPaths.push(packageJsonPath2);
981
- }
982
- }
983
- if (matchingPaths.length > 1) {
984
- throw new Error(
985
- `Found multiple packages with the name "${name}" in the repository: ${matchingPaths.join(", ")}`
986
- );
987
- }
988
- if (matchingPaths.length === 0) {
989
- throw new Error(
990
- `Could not find package with the name "${name}" in the repository`
991
- );
992
- }
993
- const [packageJsonPath] = matchingPaths;
994
- return dirname(packageJsonPath);
995
- } catch (error) {
996
- return null;
997
- }
998
- }
999
- function findPackagePath(opts) {
1000
- const cacheKey = `${opts.repositoryRoot}-${opts.name}`;
1001
- if (configCache[cacheKey]) {
1002
- return configCache[cacheKey];
1003
- }
1004
- const result = findPackagePathWithGlob(opts);
1005
- if (!result) {
1006
- throw new Error(
1007
- `Could not find package with the name "${opts.name}" in the repository`
1008
- );
1009
- }
1010
- configCache[cacheKey] = result;
1011
- return result;
1012
- }
1013
-
1014
- // src/config/microfrontends/utils/find-default-package.ts
1015
- import { dirname as dirname2 } from "node:path";
1016
- import { readFileSync as readFileSync2 } from "node:fs";
1017
- import { parse as parse2 } from "jsonc-parser";
1018
- import fg2 from "fast-glob";
1019
-
1020
- // src/config/constants.ts
1021
- var CONFIGURATION_FILENAMES = [
1022
- "microfrontends.jsonc",
1023
- "microfrontends.json"
1024
- ];
1025
-
1026
- // src/config/microfrontends/utils/find-default-package.ts
1027
- var configCache2 = {};
1028
- function findDefaultMicrofrontendsPackages({
1029
- repositoryRoot,
1030
- applicationName
1031
- }) {
1032
- try {
1033
- const microfrontendsJsonPaths = fg2.globSync(
1034
- `**/{${CONFIGURATION_FILENAMES.join(",")}}`,
1035
- {
1036
- cwd: repositoryRoot,
1037
- absolute: true,
1038
- onlyFiles: true,
1039
- followSymbolicLinks: false,
1040
- ignore: ["**/node_modules/**", "**/.git/**"]
1041
- }
1042
- );
1043
- const matchingPaths = [];
1044
- for (const microfrontendsJsonPath of microfrontendsJsonPaths) {
1045
- try {
1046
- const microfrontendsJsonContent = readFileSync2(
1047
- microfrontendsJsonPath,
1048
- "utf-8"
1049
- );
1050
- const microfrontendsJson = parse2(microfrontendsJsonContent);
1051
- if (isMainConfig(microfrontendsJson) && microfrontendsJson.applications[applicationName]) {
1052
- matchingPaths.push(microfrontendsJsonPath);
1053
- }
1054
- } catch (error) {
1055
- }
1056
- }
1057
- if (matchingPaths.length > 1) {
1058
- throw new Error(
1059
- `Found multiple default applications referencing "${applicationName}" in the repository, this is not yet supported.
1060
- ${matchingPaths.join("\n \u2022 ")}`
1061
- );
1062
- }
1063
- if (matchingPaths.length === 0) {
1064
- throw new Error(
1065
- `Could not find default application with "applications.${applicationName}"`
1066
- );
1067
- }
1068
- const [packageJsonPath] = matchingPaths;
1069
- return dirname2(packageJsonPath);
1070
- } catch (error) {
1071
- return null;
1072
- }
1073
- }
1074
- function findDefaultMicrofrontendsPackage(opts) {
1075
- const cacheKey = `${opts.repositoryRoot}-${opts.applicationName}`;
1076
- if (configCache2[cacheKey]) {
1077
- return configCache2[cacheKey];
1078
- }
1079
- const result = findDefaultMicrofrontendsPackages(opts);
1080
- if (!result) {
1081
- throw new Error(
1082
- "Error trying to resolve the main microfrontends configuration"
1083
- );
1084
- }
1085
- configCache2[cacheKey] = result;
1086
- return result;
1087
- }
1088
-
1089
- // src/config/microfrontends/utils/is-monorepo.ts
1090
- import fs2 from "node:fs";
1091
- import path2 from "node:path";
1092
- function isMonorepo({
1093
- repositoryRoot
1094
- }) {
1095
- try {
1096
- if (fs2.existsSync(path2.join(repositoryRoot, "pnpm-workspace.yaml"))) {
1097
- return true;
1098
- }
1099
- if (fs2.existsSync(path2.join(repositoryRoot, "vlt-workspaces.json"))) {
1100
- return true;
1101
- }
1102
- if (process.env.NX_WORKSPACE_ROOT === path2.resolve(repositoryRoot)) {
1103
- return true;
1104
- }
1105
- const packageJsonPath = path2.join(repositoryRoot, "package.json");
1106
- if (!fs2.existsSync(packageJsonPath)) {
1107
- return false;
1108
- }
1109
- const packageJson = JSON.parse(
1110
- fs2.readFileSync(packageJsonPath, "utf-8")
1111
- );
1112
- return packageJson.workspaces !== void 0;
1113
- } catch (error) {
1114
- console.error("Error determining if repository is a monorepo", error);
1115
- return false;
1116
- }
1117
- }
1118
-
1119
- // src/config/microfrontends/utils/find-package-root.ts
1120
- import fs3 from "node:fs";
1121
- import path3 from "node:path";
1122
- var PACKAGE_JSON = "package.json";
1123
- function findPackageRoot(startDir) {
1124
- let currentDir = startDir || process.cwd();
1125
- while (currentDir !== path3.parse(currentDir).root) {
1126
- const pkgJsonPath = path3.join(currentDir, PACKAGE_JSON);
1127
- if (fs3.existsSync(pkgJsonPath)) {
1128
- return currentDir;
1129
- }
1130
- currentDir = path3.dirname(currentDir);
1131
- }
1132
- throw new Error(
1133
- "Package root not found. Specify the root of the package with the `package.root` option."
1134
- );
1135
- }
1136
-
1137
- // src/config/microfrontends/utils/find-config.ts
1138
- import fs4 from "node:fs";
1139
- import { join } from "node:path";
1140
- function findConfig({ dir }) {
1141
- for (const filename of CONFIGURATION_FILENAMES) {
1142
- const maybeConfig = join(dir, filename);
1143
- if (fs4.existsSync(maybeConfig)) {
1144
- return maybeConfig;
1145
- }
1146
- }
1147
- return null;
1148
- }
1149
-
1150
993
  // src/config/microfrontends/utils/get-application-context.ts
1151
994
  import fs5 from "node:fs";
1152
995
  import path4 from "node:path";
@@ -1203,16 +1046,6 @@ var schema_default = {
1203
1046
  $ref: "#/definitions/Config",
1204
1047
  definitions: {
1205
1048
  Config: {
1206
- anyOf: [
1207
- {
1208
- $ref: "#/definitions/MainConfig"
1209
- },
1210
- {
1211
- $ref: "#/definitions/ChildConfig"
1212
- }
1213
- ]
1214
- },
1215
- MainConfig: {
1216
1049
  type: "object",
1217
1050
  properties: {
1218
1051
  $schema: {
@@ -1469,27 +1302,6 @@ var schema_default = {
1469
1302
  },
1470
1303
  required: ["paths"],
1471
1304
  additionalProperties: false
1472
- },
1473
- ChildConfig: {
1474
- type: "object",
1475
- properties: {
1476
- $schema: {
1477
- type: "string"
1478
- },
1479
- version: {
1480
- type: "string",
1481
- const: "1"
1482
- },
1483
- options: {
1484
- $ref: "#/definitions/Options"
1485
- },
1486
- partOf: {
1487
- type: "string",
1488
- 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."
1489
- }
1490
- },
1491
- required: ["partOf"],
1492
- additionalProperties: false
1493
1305
  }
1494
1306
  }
1495
1307
  };
@@ -1498,13 +1310,54 @@ var schema_default = {
1498
1310
  var SCHEMA = schema_default;
1499
1311
 
1500
1312
  // src/config/microfrontends/server/validation.ts
1501
- function filterAjvErrors(errors) {
1313
+ var LIST_FORMATTER2 = new Intl.ListFormat("en", {
1314
+ style: "long",
1315
+ type: "disjunction"
1316
+ });
1317
+ function formatAjvErrors(errors) {
1502
1318
  if (!errors) {
1503
1319
  return [];
1504
1320
  }
1505
- return errors.filter((error) => {
1506
- return error.keyword === "additionalProperties" || error.keyword === "required";
1507
- });
1321
+ const errorMessages = [];
1322
+ for (const error of errors) {
1323
+ if (error.instancePath === "" && (error.keyword === "anyOf" || error.keyword === "required" && error.params.missingProperty === "partOf")) {
1324
+ continue;
1325
+ }
1326
+ const instancePath = error.instancePath.slice(1);
1327
+ const formattedInstancePath = instancePath === "" ? "at the root" : `in field ${instancePath}`;
1328
+ if (error.keyword === "required" && error.params.missingProperty === "routing" && instancePath.split("/").length === 2) {
1329
+ errorMessages.push(
1330
+ `Unable to infer if ${instancePath} is the default app or a child app. This usually means that there is another error in the configuration.`
1331
+ );
1332
+ } else if (error.keyword === "anyOf" && instancePath.split("/").length > 2) {
1333
+ const anyOfErrors = errors.filter(
1334
+ (e) => e.instancePath === error.instancePath && e.keyword !== "anyOf"
1335
+ );
1336
+ if (anyOfErrors.every((e) => e.keyword === "type")) {
1337
+ const allowedTypes = LIST_FORMATTER2.format(
1338
+ anyOfErrors.map((e) => {
1339
+ return e.keyword === "type" ? String(e.params.type) : "unknown";
1340
+ })
1341
+ );
1342
+ errorMessages.push(
1343
+ `Incorrect type for ${instancePath}. Must be one of ${allowedTypes}`
1344
+ );
1345
+ } else {
1346
+ errorMessages.push(
1347
+ `Invalid field for ${instancePath}. Possible error messages are ${LIST_FORMATTER2.format(anyOfErrors.map((e) => e.message ?? ""))}`
1348
+ );
1349
+ }
1350
+ } else if (error.keyword === "additionalProperties" && !(error.params.additionalProperty === "routing" && instancePath.split("/").length === 2)) {
1351
+ errorMessages.push(
1352
+ `Property '${error.params.additionalProperty}' is not allowed ${formattedInstancePath}`
1353
+ );
1354
+ } else if (error.keyword === "required") {
1355
+ errorMessages.push(
1356
+ `Property '${error.params.missingProperty}' is required ${formattedInstancePath}`
1357
+ );
1358
+ }
1359
+ }
1360
+ return errorMessages;
1508
1361
  }
1509
1362
  function validateSchema(configString) {
1510
1363
  const parsedConfig = parse3(configString);
@@ -1513,8 +1366,10 @@ function validateSchema(configString) {
1513
1366
  const isValid = validate(parsedConfig);
1514
1367
  if (!isValid) {
1515
1368
  throw new MicrofrontendError(
1516
- `Invalid microfrontends config:
1517
- - ${ajv.errorsText(filterAjvErrors(validate.errors), { separator: "\n - " })}
1369
+ `Invalid microfrontends config:${formatAjvErrors(validate.errors).map((error) => `
1370
+ - ${error}`).join(
1371
+ ""
1372
+ )}
1518
1373
 
1519
1374
  See https://openapi.vercel.sh/microfrontends.json for the schema.`,
1520
1375
  { type: "config", subtype: "does_not_match_schema" }
@@ -1524,7 +1379,13 @@ See https://openapi.vercel.sh/microfrontends.json for the schema.`,
1524
1379
  }
1525
1380
 
1526
1381
  // src/config/microfrontends/server/index.ts
1527
- var MicrofrontendsServer = class extends Microfrontends {
1382
+ var MicrofrontendsServer = class {
1383
+ constructor({
1384
+ config,
1385
+ overrides
1386
+ }) {
1387
+ this.config = new MicrofrontendConfigIsomorphic({ config, overrides });
1388
+ }
1528
1389
  /**
1529
1390
  * Writes the configuration to a file.
1530
1391
  */
@@ -1532,7 +1393,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1532
1393
  pretty: true
1533
1394
  }) {
1534
1395
  const outputPath = getOutputFilePath();
1535
- fs6.mkdirSync(dirname3(outputPath), { recursive: true });
1396
+ fs6.mkdirSync(dirname2(outputPath), { recursive: true });
1536
1397
  fs6.writeFileSync(
1537
1398
  outputPath,
1538
1399
  JSON.stringify(
@@ -1548,22 +1409,19 @@ var MicrofrontendsServer = class extends Microfrontends {
1548
1409
  */
1549
1410
  static fromUnknown({
1550
1411
  config,
1551
- cookies,
1552
- meta
1412
+ cookies
1553
1413
  }) {
1554
1414
  const overrides = cookies ? parseOverrides(cookies) : void 0;
1555
1415
  if (typeof config === "string") {
1556
1416
  return new MicrofrontendsServer({
1557
1417
  config: MicrofrontendsServer.validate(config),
1558
- overrides,
1559
- meta
1418
+ overrides
1560
1419
  });
1561
1420
  }
1562
1421
  if (typeof config === "object") {
1563
1422
  return new MicrofrontendsServer({
1564
1423
  config,
1565
- overrides,
1566
- meta
1424
+ overrides
1567
1425
  });
1568
1426
  }
1569
1427
  throw new MicrofrontendError(
@@ -1576,13 +1434,11 @@ var MicrofrontendsServer = class extends Microfrontends {
1576
1434
  * Uses additional validation that is only available when in a node runtime
1577
1435
  */
1578
1436
  static fromEnv({
1579
- cookies,
1580
- meta
1437
+ cookies
1581
1438
  }) {
1582
1439
  return new MicrofrontendsServer({
1583
1440
  config: MicrofrontendsServer.validate(getConfigStringFromEnv()),
1584
- overrides: parseOverrides(cookies),
1585
- meta
1441
+ overrides: parseOverrides(cookies)
1586
1442
  });
1587
1443
  }
1588
1444
  /**
@@ -1605,29 +1461,22 @@ var MicrofrontendsServer = class extends Microfrontends {
1605
1461
  static infer({
1606
1462
  directory,
1607
1463
  filePath,
1608
- meta,
1609
- cookies,
1610
- options
1464
+ cookies
1611
1465
  } = {}) {
1612
- if (filePath && meta) {
1466
+ if (filePath) {
1613
1467
  return MicrofrontendsServer.fromFile({
1614
1468
  filePath,
1615
- cookies,
1616
- meta,
1617
- options
1469
+ cookies
1618
1470
  });
1619
1471
  }
1620
1472
  try {
1621
1473
  const packageRoot = findPackageRoot(directory);
1622
1474
  const { name: appName } = getApplicationContext({ packageRoot });
1623
- const configMeta = meta ?? { fromApp: appName };
1624
1475
  const maybeConfig = findConfig({ dir: packageRoot });
1625
1476
  if (maybeConfig) {
1626
1477
  return MicrofrontendsServer.fromFile({
1627
1478
  filePath: maybeConfig,
1628
- cookies,
1629
- meta: configMeta,
1630
- options
1479
+ cookies
1631
1480
  });
1632
1481
  }
1633
1482
  const repositoryRoot = findRepositoryRoot();
@@ -1641,14 +1490,15 @@ var MicrofrontendsServer = class extends Microfrontends {
1641
1490
  if (maybeConfigFromDefault) {
1642
1491
  return MicrofrontendsServer.fromFile({
1643
1492
  filePath: maybeConfigFromDefault,
1644
- cookies,
1645
- meta: configMeta,
1646
- options
1493
+ cookies
1647
1494
  });
1648
1495
  }
1649
1496
  }
1650
1497
  throw new Error("Unable to infer");
1651
1498
  } catch (e) {
1499
+ if (e instanceof MicrofrontendError) {
1500
+ throw e;
1501
+ }
1652
1502
  throw new MicrofrontendError(
1653
1503
  "Unable to locate and parse microfrontends configuration",
1654
1504
  { cause: e, type: "config", subtype: "inference_failed" }
@@ -1660,44 +1510,14 @@ var MicrofrontendsServer = class extends Microfrontends {
1660
1510
  */
1661
1511
  static fromFile({
1662
1512
  filePath,
1663
- cookies,
1664
- meta,
1665
- options
1513
+ cookies
1666
1514
  }) {
1667
1515
  try {
1668
1516
  const configJson = fs6.readFileSync(filePath, "utf-8");
1669
1517
  const config = MicrofrontendsServer.validate(configJson);
1670
- if (!isMainConfig(config) && options?.resolveMainConfig) {
1671
- const repositoryRoot = findRepositoryRoot();
1672
- const isMonorepo2 = isMonorepo({ repositoryRoot });
1673
- if (isMonorepo2) {
1674
- const packagePath = findPackagePath({
1675
- repositoryRoot,
1676
- name: config.partOf
1677
- });
1678
- if (!packagePath) {
1679
- throw new MicrofrontendError(
1680
- `Could not find default application "${config.partOf}" in the repository`,
1681
- { type: "config", subtype: "not_found" }
1682
- );
1683
- }
1684
- const maybeConfig = findConfig({ dir: packagePath });
1685
- if (!maybeConfig) {
1686
- throw new MicrofrontendError(
1687
- `Could not find microfrontends configuration in ${packagePath}`,
1688
- { type: "config", subtype: "not_found" }
1689
- );
1690
- }
1691
- return MicrofrontendsServer.fromMainConfigFile({
1692
- filePath: maybeConfig,
1693
- overrides: cookies ? parseOverrides(cookies) : void 0
1694
- });
1695
- }
1696
- }
1697
1518
  return new MicrofrontendsServer({
1698
1519
  config,
1699
- overrides: cookies ? parseOverrides(cookies) : void 0,
1700
- meta
1520
+ overrides: cookies ? parseOverrides(cookies) : void 0
1701
1521
  });
1702
1522
  } catch (e) {
1703
1523
  throw MicrofrontendError.handle(e, {
@@ -1706,7 +1526,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1706
1526
  }
1707
1527
  }
1708
1528
  /*
1709
- * Generates a MicrofrontendMainConfig instance from a file.
1529
+ * Generates a MicrofrontendsServer instance from a file.
1710
1530
  */
1711
1531
  static fromMainConfigFile({
1712
1532
  filePath,
@@ -1715,15 +1535,6 @@ var MicrofrontendsServer = class extends Microfrontends {
1715
1535
  try {
1716
1536
  const config = fs6.readFileSync(filePath, "utf-8");
1717
1537
  const validatedConfig = MicrofrontendsServer.validate(config);
1718
- if (!isMainConfig(validatedConfig)) {
1719
- throw new MicrofrontendError(
1720
- `${filePath} is not a main microfrontend config`,
1721
- {
1722
- type: "config",
1723
- subtype: "invalid_main_path"
1724
- }
1725
- );
1726
- }
1727
1538
  const [defaultApplication] = Object.entries(validatedConfig.applications).filter(([, app]) => isDefaultApp(app)).map(([name]) => name);
1728
1539
  if (!defaultApplication) {
1729
1540
  throw new MicrofrontendError(
@@ -1733,8 +1544,7 @@ var MicrofrontendsServer = class extends Microfrontends {
1733
1544
  }
1734
1545
  return new MicrofrontendsServer({
1735
1546
  config: validatedConfig,
1736
- overrides,
1737
- meta: { fromApp: defaultApplication }
1547
+ overrides
1738
1548
  });
1739
1549
  } catch (e) {
1740
1550
  throw MicrofrontendError.handle(e, {
@@ -1761,43 +1571,39 @@ function detectFramework() {
1761
1571
  // src/vite/index.ts
1762
1572
  function microfrontends(opts) {
1763
1573
  const { name: fromApp } = getApplicationContext();
1764
- const microfrontendsObj = MicrofrontendsServer.infer({
1765
- meta: {
1766
- fromApp
1767
- }
1768
- });
1574
+ const microfrontendsObj = MicrofrontendsServer.infer();
1769
1575
  const app = microfrontendsObj.config.getApplication(fromApp);
1770
1576
  if (app.isDefault() && opts?.basePath) {
1771
1577
  throw new Error(
1772
1578
  "`basePath` can not be set for the default microfrontends application."
1773
1579
  );
1774
1580
  }
1775
- if (opts?.basePath && !opts.basePath.startsWith("/")) {
1776
- throw new Error("`basePath` must start with a `/`");
1581
+ const framework = detectFramework();
1582
+ if (framework === "sveltekit" && opts?.basePath) {
1583
+ throw new Error("`basePath` is not supported for SvelteKit applications.");
1584
+ }
1585
+ if (opts?.basePath && (!opts.basePath.startsWith("/") || opts.basePath.endsWith("/"))) {
1586
+ throw new Error("`basePath` must start with a `/` and not end with a `/`");
1777
1587
  }
1778
1588
  const additionalConfigOptions = {};
1779
- const framework = detectFramework();
1780
1589
  if (!app.isDefault()) {
1781
1590
  if (opts?.basePath) {
1591
+ const basePath = opts.basePath;
1782
1592
  if (framework !== "react-router" || !process.env.VERCEL_ENV) {
1783
- let basePath = opts.basePath;
1784
- if (process.env.NODE_ENV === "production" && !basePath.endsWith("/")) {
1785
- basePath = `${basePath}/`;
1786
- }
1787
1593
  additionalConfigOptions.base = basePath;
1788
1594
  }
1595
+ if (framework === "react-router") {
1596
+ additionalConfigOptions.build = {
1597
+ assetsDir: `./${basePath}`
1598
+ };
1599
+ } else {
1600
+ additionalConfigOptions.build = {
1601
+ outDir: `dist${opts.basePath}`
1602
+ };
1603
+ }
1789
1604
  } else if (framework !== "sveltekit") {
1790
- additionalConfigOptions.experimental = {
1791
- renderBuiltUrl(filename, { type }) {
1792
- if (type === "asset") {
1793
- return `/${app.getAssetPrefix()}/${filename}`;
1794
- }
1795
- }
1796
- };
1797
- }
1798
- if (framework !== "sveltekit") {
1799
1605
  additionalConfigOptions.build = {
1800
- assetsDir: `./${opts?.basePath ?? app.getAssetPrefix()}`
1606
+ assetsDir: `./${app.getAssetPrefix()}`
1801
1607
  };
1802
1608
  }
1803
1609
  }
@@ -1805,6 +1611,15 @@ function microfrontends(opts) {
1805
1611
  additionalConfigOptions.server = {
1806
1612
  port: app.development.local.port
1807
1613
  };
1614
+ additionalConfigOptions.preview = {
1615
+ port: app.development.local.port
1616
+ };
1617
+ }
1618
+ if (process.env.MFE_DEBUG) {
1619
+ console.log(
1620
+ "[@vercel/microfrontends] Updating Vite configuration with the following changes:",
1621
+ additionalConfigOptions
1622
+ );
1808
1623
  }
1809
1624
  return {
1810
1625
  name: "vite-plugin-vercel-microfrontends",