@nocobase/plugin-multi-portal 3.0.0-alpha.2 → 3.0.0-alpha.3

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.
@@ -8,19 +8,19 @@
8
8
  */
9
9
 
10
10
  module.exports = {
11
- "@nocobase/flow-engine": "3.0.0-alpha.2",
12
- "@nocobase/client": "3.0.0-alpha.2",
13
- "@nocobase/client-v2": "3.0.0-alpha.2",
11
+ "@nocobase/flow-engine": "3.0.0-alpha.3",
12
+ "@nocobase/client": "3.0.0-alpha.3",
13
+ "@nocobase/client-v2": "3.0.0-alpha.3",
14
14
  "antd": "5.24.2",
15
15
  "react": "18.2.0",
16
16
  "react-router-dom": "6.30.1",
17
- "@nocobase/database": "3.0.0-alpha.2",
18
- "@nocobase/server": "3.0.0-alpha.2",
19
- "@nocobase/resourcer": "3.0.0-alpha.2",
20
- "@nocobase/utils": "3.0.0-alpha.2",
17
+ "@nocobase/database": "3.0.0-alpha.3",
18
+ "@nocobase/server": "3.0.0-alpha.3",
19
+ "@nocobase/resourcer": "3.0.0-alpha.3",
20
+ "@nocobase/utils": "3.0.0-alpha.3",
21
21
  "ahooks": "3.7.8",
22
22
  "antd-style": "3.7.1",
23
- "@nocobase/plugin-ui-layout": "3.0.0-alpha.2",
23
+ "@nocobase/plugin-ui-layout": "3.0.0-alpha.3",
24
24
  "@ant-design/icons": "5.6.1",
25
25
  "sequelize": "6.35.2"
26
26
  };
@@ -1 +1 @@
1
- {"author":"Isaac Z. Schlueter","name":"tar","description":"tar for node","version":"7.5.15","repository":{"type":"git","url":"https://github.com/isaacs/node-tar.git"},"scripts":{"genparse":"node scripts/generate-parse-fixtures.js","snap":"tap","test":"tap","pretest":"npm run prepare","presnap":"npm run prepare","prepare":"tshy && bash scripts/build.sh","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","format":"prettier --write . --log-level warn","typedoc":"typedoc --tsconfig .tshy/esm.json ./src/*.ts","lint":"oxlint --fix src test","postsnap":"npm run lint","postlint":"npm run format"},"dependencies":{"@isaacs/fs-minipass":"^4.0.0","chownr":"^3.0.0","minipass":"^7.1.2","minizlib":"^3.1.0","yallist":"^5.0.0"},"devDependencies":{"@types/node":"^25.5.0","chmodr":"^2.0.2","end-of-stream":"^1.4.3","esbuild":"^0.27.4","events-to-array":"^2.0.3","mutate-fs":"^2.1.1","nock":"^13.5.4","oxlint":"^1.57.0","oxlint-tsgolint":"^0.17.3","prettier":"^3.8.1","rimraf":"^6.1.2","tap":"^21.6.2","tshy":"^3.3.2","typedoc":"^0.28.18"},"license":"BlueOak-1.0.0","engines":{"node":">=18"},"files":["dist"],"tshy":{"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":"./src/index.ts","./c":"./src/create.ts","./create":"./src/create.ts","./replace":"./src/create.ts","./r":"./src/create.ts","./list":"./src/list.ts","./t":"./src/list.ts","./update":"./src/update.ts","./u":"./src/update.ts","./extract":"./src/extract.ts","./x":"./src/extract.ts","./pack":"./src/pack.ts","./unpack":"./src/unpack.ts","./parse":"./src/parse.ts","./read-entry":"./src/read-entry.ts","./write-entry":"./src/write-entry.ts","./header":"./src/header.ts","./pax":"./src/pax.ts","./types":"./src/types.ts"}},"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.js"}},"./c":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./create":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./replace":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./r":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./list":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./t":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./update":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./u":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./extract":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./x":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./pack":{"import":{"types":"./dist/esm/pack.d.ts","default":"./dist/esm/pack.js"},"require":{"types":"./dist/commonjs/pack.d.ts","default":"./dist/commonjs/pack.js"}},"./unpack":{"import":{"types":"./dist/esm/unpack.d.ts","default":"./dist/esm/unpack.js"},"require":{"types":"./dist/commonjs/unpack.d.ts","default":"./dist/commonjs/unpack.js"}},"./parse":{"import":{"types":"./dist/esm/parse.d.ts","default":"./dist/esm/parse.js"},"require":{"types":"./dist/commonjs/parse.d.ts","default":"./dist/commonjs/parse.js"}},"./read-entry":{"import":{"types":"./dist/esm/read-entry.d.ts","default":"./dist/esm/read-entry.js"},"require":{"types":"./dist/commonjs/read-entry.d.ts","default":"./dist/commonjs/read-entry.js"}},"./write-entry":{"import":{"types":"./dist/esm/write-entry.d.ts","default":"./dist/esm/write-entry.js"},"require":{"types":"./dist/commonjs/write-entry.d.ts","default":"./dist/commonjs/write-entry.js"}},"./header":{"import":{"types":"./dist/esm/header.d.ts","default":"./dist/esm/header.js"},"require":{"types":"./dist/commonjs/header.d.ts","default":"./dist/commonjs/header.js"}},"./pax":{"import":{"types":"./dist/esm/pax.d.ts","default":"./dist/esm/pax.js"},"require":{"types":"./dist/commonjs/pax.d.ts","default":"./dist/commonjs/pax.js"}},"./types":{"import":{"types":"./dist/esm/types.d.ts","default":"./dist/esm/types.js"},"require":{"types":"./dist/commonjs/types.d.ts","default":"./dist/commonjs/types.js"}}},"type":"module","main":"./dist/commonjs/index.min.js","types":"./dist/commonjs/index.d.ts","module":"./dist/esm/index.min.js","_lastModified":"2026-07-30T05:57:24.832Z"}
1
+ {"author":"Isaac Z. Schlueter","name":"tar","description":"tar for node","version":"7.5.15","repository":{"type":"git","url":"https://github.com/isaacs/node-tar.git"},"scripts":{"genparse":"node scripts/generate-parse-fixtures.js","snap":"tap","test":"tap","pretest":"npm run prepare","presnap":"npm run prepare","prepare":"tshy && bash scripts/build.sh","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","format":"prettier --write . --log-level warn","typedoc":"typedoc --tsconfig .tshy/esm.json ./src/*.ts","lint":"oxlint --fix src test","postsnap":"npm run lint","postlint":"npm run format"},"dependencies":{"@isaacs/fs-minipass":"^4.0.0","chownr":"^3.0.0","minipass":"^7.1.2","minizlib":"^3.1.0","yallist":"^5.0.0"},"devDependencies":{"@types/node":"^25.5.0","chmodr":"^2.0.2","end-of-stream":"^1.4.3","esbuild":"^0.27.4","events-to-array":"^2.0.3","mutate-fs":"^2.1.1","nock":"^13.5.4","oxlint":"^1.57.0","oxlint-tsgolint":"^0.17.3","prettier":"^3.8.1","rimraf":"^6.1.2","tap":"^21.6.2","tshy":"^3.3.2","typedoc":"^0.28.18"},"license":"BlueOak-1.0.0","engines":{"node":">=18"},"files":["dist"],"tshy":{"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":"./src/index.ts","./c":"./src/create.ts","./create":"./src/create.ts","./replace":"./src/create.ts","./r":"./src/create.ts","./list":"./src/list.ts","./t":"./src/list.ts","./update":"./src/update.ts","./u":"./src/update.ts","./extract":"./src/extract.ts","./x":"./src/extract.ts","./pack":"./src/pack.ts","./unpack":"./src/unpack.ts","./parse":"./src/parse.ts","./read-entry":"./src/read-entry.ts","./write-entry":"./src/write-entry.ts","./header":"./src/header.ts","./pax":"./src/pax.ts","./types":"./src/types.ts"}},"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.js"}},"./c":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./create":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./replace":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./r":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./list":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./t":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./update":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./u":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./extract":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./x":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./pack":{"import":{"types":"./dist/esm/pack.d.ts","default":"./dist/esm/pack.js"},"require":{"types":"./dist/commonjs/pack.d.ts","default":"./dist/commonjs/pack.js"}},"./unpack":{"import":{"types":"./dist/esm/unpack.d.ts","default":"./dist/esm/unpack.js"},"require":{"types":"./dist/commonjs/unpack.d.ts","default":"./dist/commonjs/unpack.js"}},"./parse":{"import":{"types":"./dist/esm/parse.d.ts","default":"./dist/esm/parse.js"},"require":{"types":"./dist/commonjs/parse.d.ts","default":"./dist/commonjs/parse.js"}},"./read-entry":{"import":{"types":"./dist/esm/read-entry.d.ts","default":"./dist/esm/read-entry.js"},"require":{"types":"./dist/commonjs/read-entry.d.ts","default":"./dist/commonjs/read-entry.js"}},"./write-entry":{"import":{"types":"./dist/esm/write-entry.d.ts","default":"./dist/esm/write-entry.js"},"require":{"types":"./dist/commonjs/write-entry.d.ts","default":"./dist/commonjs/write-entry.js"}},"./header":{"import":{"types":"./dist/esm/header.d.ts","default":"./dist/esm/header.js"},"require":{"types":"./dist/commonjs/header.d.ts","default":"./dist/commonjs/header.js"}},"./pax":{"import":{"types":"./dist/esm/pax.d.ts","default":"./dist/esm/pax.js"},"require":{"types":"./dist/commonjs/pax.d.ts","default":"./dist/commonjs/pax.js"}},"./types":{"import":{"types":"./dist/esm/types.d.ts","default":"./dist/esm/types.js"},"require":{"types":"./dist/commonjs/types.d.ts","default":"./dist/commonjs/types.js"}}},"type":"module","main":"./dist/commonjs/index.min.js","types":"./dist/commonjs/index.d.ts","module":"./dist/esm/index.min.js","_lastModified":"2026-07-30T10:32:21.491Z"}
@@ -31,7 +31,7 @@ export declare class PluginMultiPortalServer extends Plugin {
31
31
  private logPortalBuildHtml;
32
32
  private getPortalStorageTaskKey;
33
33
  private runPortalStorageTask;
34
- private removePortalStorageDist;
34
+ private removePortalStorageIndexHtml;
35
35
  private waitForPortalStorageTasks;
36
36
  private schedulePortalTemplateCopyAndBuild;
37
37
  private ensurePortalStorageItem;
@@ -597,12 +597,14 @@ async function buildPortalStorageItem(portalDir, item) {
597
597
  const buildEnv = getPortalStorageCommandEnv({
598
598
  NOCOBASE_API_URL: getPortalStorageApiUrl(item.appName),
599
599
  NOCOBASE_PORTAL_BASE: getPortalDeployBasePath(item.appName, item.portalName),
600
+ SKIP_YARN_COREPACK_CHECK: "1",
601
+ COREPACK_ENABLE_STRICT: "0",
600
602
  COREPACK_ENABLE_PROJECT_SPEC: "0"
601
603
  });
602
604
  await appendPortalStorageLog(logPath, `Building portal ${item.appName}/${item.portalName}.`);
603
605
  await appendPortalStorageLog(
604
606
  logPath,
605
- `Build environment: NOCOBASE_API_URL=${buildEnv.NOCOBASE_API_URL || ""} NOCOBASE_PORTAL_BASE=${buildEnv.NOCOBASE_PORTAL_BASE || ""} APP_PUBLIC_PATH=${buildEnv.APP_PUBLIC_PATH || ""}`
607
+ `Build environment: NOCOBASE_API_URL=${buildEnv.NOCOBASE_API_URL || ""} NOCOBASE_PORTAL_BASE=${buildEnv.NOCOBASE_PORTAL_BASE || ""} APP_PUBLIC_PATH=${buildEnv.APP_PUBLIC_PATH || ""} SKIP_YARN_COREPACK_CHECK=${buildEnv.SKIP_YARN_COREPACK_CHECK || ""} COREPACK_ENABLE_STRICT=${buildEnv.COREPACK_ENABLE_STRICT || ""} COREPACK_ENABLE_PROJECT_SPEC=${buildEnv.COREPACK_ENABLE_PROJECT_SPEC || ""}`
606
608
  );
607
609
  await runPortalStorageCommandOnce("yarn", ["build:html"], {
608
610
  cwd: portalDir,
@@ -1095,39 +1097,6 @@ async function seedHistoricalMultiPortals(db) {
1095
1097
  }
1096
1098
  await repairFixedLayoutMultiPortalRecords(db);
1097
1099
  }
1098
- async function preventUiLayoutRouteNameConflict(ctx, next) {
1099
- const targets = await getMultiPortalWriteTargets(ctx, ["uid", "portalName", "uiLayoutUid"]);
1100
- for (const { existing, values } of targets) {
1101
- const existingUid = trimString(existing == null ? void 0 : existing.get("uid"));
1102
- const uid = trimString(values.uid ?? existingUid);
1103
- const portalName = trimString(values.portalName ?? (existing == null ? void 0 : existing.get("portalName")));
1104
- const uiLayoutUid = trimString(values.uiLayoutUid ?? (existing == null ? void 0 : existing.get("uiLayoutUid")));
1105
- const fixedPortal = getFixedLayoutMultiPortalRecord(existingUid) || getFixedLayoutMultiPortalRecord(uid);
1106
- const canonicalPortal = (fixedPortal == null ? void 0 : fixedPortal.uid) === uid && (!existingUid || fixedPortal.uid === existingUid) && fixedPortal.portalName === portalName && fixedPortal.uiLayoutUid === uiLayoutUid;
1107
- if (fixedPortal && !canonicalPortal) {
1108
- ctx.throw(400, "Reserved Portal UID must match its canonical route and UI layout");
1109
- return;
1110
- }
1111
- if (!portalName) {
1112
- continue;
1113
- }
1114
- if (portalName === "admin" || portalName === "mobile") {
1115
- continue;
1116
- }
1117
- const existingInitPortal = (existing == null ? void 0 : existing.get("uid")) === DEFAULT_MULTI_PORTAL_UID && existing.get("portalName") === portalName;
1118
- const uiLayout = await ctx.db.getRepository("uiLayouts").findOne({
1119
- filter: {
1120
- routeName: portalName
1121
- },
1122
- fields: ["uid"]
1123
- });
1124
- if (uiLayout && !existingInitPortal) {
1125
- ctx.throw(400, "Portal route name conflicts with an existing UI layout");
1126
- return;
1127
- }
1128
- }
1129
- await next();
1130
- }
1131
1100
  async function preventMultiPortalBackingLayoutChange(ctx, next) {
1132
1101
  const targets = await getMultiPortalWriteTargets(ctx, ["uiLayoutUid"]);
1133
1102
  for (const { existing, values } of targets) {
@@ -1242,7 +1211,6 @@ async function assertDesktopRouteParentsBelongToScope(ctx, scope, values = ((_a)
1242
1211
  id: parentIds,
1243
1212
  ...scope.filter
1244
1213
  },
1245
- ...transaction ? { lock: transaction.LOCK.UPDATE } : {},
1246
1214
  transaction
1247
1215
  });
1248
1216
  if (new Set(normalizeDesktopRouteTargetIds(parents)).size !== new Set(parentIds.map(String)).size) {
@@ -1276,7 +1244,6 @@ async function assertDesktopRouteUpsertMatchesBelongToScope(ctx, scope, values =
1276
1244
  ...filter,
1277
1245
  ...scope.filter
1278
1246
  },
1279
- ...transaction ? { lock: transaction.LOCK.UPDATE } : {},
1280
1247
  transaction
1281
1248
  });
1282
1249
  const allMatchIds = normalizeDesktopRouteTargetIds(allMatches);
@@ -1691,7 +1658,7 @@ async function findDesktopRouteMutationTargets(ctx, scopeFilter, transaction, se
1691
1658
  ...filter ?? {},
1692
1659
  ...scopeFilter ?? {}
1693
1660
  },
1694
- ...transaction ? { lock: transaction.LOCK.UPDATE } : {},
1661
+ ...transaction && !scopeFilter ? { lock: transaction.LOCK.UPDATE } : {},
1695
1662
  transaction
1696
1663
  });
1697
1664
  }
@@ -1843,7 +1810,6 @@ async function guardDesktopRouteMoveScope(ctx, next) {
1843
1810
  id: routeIds,
1844
1811
  ...scope.filter
1845
1812
  },
1846
- lock: transaction.LOCK.UPDATE,
1847
1813
  transaction
1848
1814
  });
1849
1815
  if (normalizeDesktopRouteTargetIds(allRoutes).join(",") !== normalizeDesktopRouteTargetIds(scopedRoutes).join(",") || scopedRoutes.length !== routeIds.length) {
@@ -1873,7 +1839,6 @@ async function guardDesktopRouteMoveScope(ctx, next) {
1873
1839
  id: parentIds,
1874
1840
  ...scope.filter
1875
1841
  },
1876
- lock: transaction.LOCK.UPDATE,
1877
1842
  transaction
1878
1843
  });
1879
1844
  if (normalizeDesktopRouteTargetIds(parents).join(",") !== parentIds.map(String).sort().join(",")) {
@@ -1921,7 +1886,6 @@ async function guardDesktopRouteMoveScope(ctx, next) {
1921
1886
  $gte: targetSort
1922
1887
  }
1923
1888
  },
1924
- lock: transaction.LOCK.UPDATE,
1925
1889
  transaction
1926
1890
  });
1927
1891
  const affectedRouteIds = affectedRoutes.map((route) => route.get("id"));
@@ -2019,7 +1983,7 @@ async function findDesktopRouteDestroyRoots(ctx, transaction, scopeFilter) {
2019
1983
  ...scopeFilter ?? {},
2020
1984
  ...filterByTk.length ? { id: filterByTk } : {}
2021
1985
  },
2022
- lock: transaction.LOCK.UPDATE,
1986
+ ...scopeFilter ? {} : { lock: transaction.LOCK.UPDATE },
2023
1987
  transaction
2024
1988
  });
2025
1989
  return collectDesktopRouteIds(records);
@@ -2085,13 +2049,20 @@ async function detachDesktopRouteTreeOwner(ctx, routeIds, scope, transaction) {
2085
2049
  }
2086
2050
  async function detachOwnerAndFindDestroyRoots(ctx, routeIds, scope, transaction) {
2087
2051
  var _a;
2052
+ await ctx.db.getRepository("desktopRoutes").find({
2053
+ fields: ["id"],
2054
+ filter: {
2055
+ id: routeIds
2056
+ },
2057
+ lock: transaction.LOCK.UPDATE,
2058
+ transaction
2059
+ });
2088
2060
  const routes = await ctx.db.getRepository("desktopRoutes").find({
2089
2061
  fields: ["id", "parentId"],
2090
2062
  appends: ["multiPortals", "uiLayouts"],
2091
2063
  filter: {
2092
2064
  id: routeIds
2093
2065
  },
2094
- lock: transaction.LOCK.UPDATE,
2095
2066
  transaction
2096
2067
  });
2097
2068
  const routesById = new Map(routes.map((route) => [String(route.get("id")), route]));
@@ -2399,10 +2370,9 @@ class PluginMultiPortalServer extends import_server.Plugin {
2399
2370
  }
2400
2371
  await run();
2401
2372
  }
2402
- async removePortalStorageDist(item) {
2403
- await import_fs.default.promises.rm((0, import_utils.storagePathJoin)("portals", item.appName, item.portalName, "dist"), {
2404
- force: true,
2405
- recursive: true
2373
+ async removePortalStorageIndexHtml(item) {
2374
+ await import_fs.default.promises.rm((0, import_utils.storagePathJoin)("portals", item.appName, item.portalName, "dist", "index.html"), {
2375
+ force: true
2406
2376
  });
2407
2377
  }
2408
2378
  waitForPortalStorageTasks() {
@@ -2446,8 +2416,8 @@ class PluginMultiPortalServer extends import_server.Plugin {
2446
2416
  return;
2447
2417
  }
2448
2418
  this.logPortalBuildHtml(item, "skipped", "the portal is disabled");
2449
- await this.removePortalStorageDist(item);
2450
- await appendPortalStorageLog(logPath, `Portal dist directory removed for ${item.appName}/${item.portalName}.`);
2419
+ await this.removePortalStorageIndexHtml(item);
2420
+ await appendPortalStorageLog(logPath, `Portal index.html removed for ${item.appName}/${item.portalName}.`);
2451
2421
  } catch (error) {
2452
2422
  await appendPortalStorageLog(
2453
2423
  logPath,
@@ -2489,15 +2459,15 @@ class PluginMultiPortalServer extends import_server.Plugin {
2489
2459
  return;
2490
2460
  }
2491
2461
  this.logPortalBuildHtml(item, "skipped", "the portal is disabled");
2492
- await this.removePortalStorageDist(item);
2493
- await appendPortalStorageLog(logPath, `Portal dist directory removed for ${item.appName}/${item.portalName}.`);
2462
+ await this.removePortalStorageIndexHtml(item);
2463
+ await appendPortalStorageLog(logPath, `Portal index.html removed for ${item.appName}/${item.portalName}.`);
2494
2464
  }
2495
2465
  async syncMultiPortalStorageItem(multiPortal, options, syncPrevious = false, forceBuild = false) {
2496
2466
  const currentItem = this.getMultiPortalStorageItem(multiPortal);
2497
2467
  const previousItem = syncPrevious ? this.getMultiPortalStorageItem(multiPortal, true) : null;
2498
2468
  await this.runPortalStorageTask(async () => {
2499
2469
  if (previousItem && (!currentItem || previousItem.appName !== currentItem.appName || previousItem.portalName !== currentItem.portalName || !currentItem.enabled)) {
2500
- await this.removePortalStorageDist(previousItem);
2470
+ await this.removePortalStorageIndexHtml(previousItem);
2501
2471
  }
2502
2472
  if (currentItem) {
2503
2473
  await this.ensurePortalStorageItem(currentItem, { forceBuild });
@@ -2849,24 +2819,20 @@ class PluginMultiPortalServer extends import_server.Plugin {
2849
2819
  );
2850
2820
  this.app.resourceManager.registerPreActionHandler("multiPortals:create", captureSkipCreatePortalDirectory);
2851
2821
  this.app.resourceManager.registerPreActionHandler("multiPortals:create", normalizeMultiPortalSlugValues);
2852
- this.app.resourceManager.registerPreActionHandler("multiPortals:create", preventUiLayoutRouteNameConflict);
2853
2822
  this.app.resourceManager.registerPreActionHandler("multiPortals:update", preventMultiPortalBackingLayoutChange);
2854
2823
  this.app.resourceManager.registerPreActionHandler("multiPortals:update", normalizeMultiPortalSlugValues);
2855
- this.app.resourceManager.registerPreActionHandler("multiPortals:update", preventUiLayoutRouteNameConflict);
2856
2824
  this.app.resourceManager.registerPreActionHandler(
2857
2825
  "multiPortals:firstOrCreate",
2858
2826
  preventMultiPortalBackingLayoutChange
2859
2827
  );
2860
2828
  this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", captureSkipCreatePortalDirectory);
2861
2829
  this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", normalizeMultiPortalSlugValues);
2862
- this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", preventUiLayoutRouteNameConflict);
2863
2830
  this.app.resourceManager.registerPreActionHandler(
2864
2831
  "multiPortals:updateOrCreate",
2865
2832
  preventMultiPortalBackingLayoutChange
2866
2833
  );
2867
2834
  this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", captureSkipCreatePortalDirectory);
2868
2835
  this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", normalizeMultiPortalSlugValues);
2869
- this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", preventUiLayoutRouteNameConflict);
2870
2836
  this.app.resourceManager.registerPreActionHandler("desktopRoutes:create", addDesktopRouteCreateMultiPortal, {
2871
2837
  after: UI_LAYOUT_DESKTOP_ROUTE_WRITE_LAYOUT_HANDLER_TAG
2872
2838
  });
@@ -0,0 +1,152 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ declare const _default: {
10
+ openapi: string;
11
+ info: {
12
+ title: string;
13
+ version: string;
14
+ };
15
+ paths: {
16
+ '/roles/{roleName}/multiPortals:list': {
17
+ get: {
18
+ tags: string[];
19
+ summary: string;
20
+ description: string;
21
+ parameters: {
22
+ $ref: string;
23
+ }[];
24
+ responses: {
25
+ 200: {
26
+ description: string;
27
+ content: {
28
+ 'application/json': {
29
+ schema: {
30
+ type: string;
31
+ properties: {
32
+ data: {
33
+ type: string;
34
+ items: {
35
+ $ref: string;
36
+ };
37
+ };
38
+ };
39
+ };
40
+ };
41
+ };
42
+ };
43
+ };
44
+ };
45
+ };
46
+ '/roles/{roleName}/multiPortals:add': {
47
+ post: {
48
+ tags: string[];
49
+ summary: string;
50
+ description: string;
51
+ parameters: {
52
+ $ref: string;
53
+ }[];
54
+ requestBody: {
55
+ required: boolean;
56
+ content: {
57
+ 'application/json': {
58
+ schema: {
59
+ $ref: string;
60
+ };
61
+ };
62
+ };
63
+ };
64
+ responses: {
65
+ 200: {
66
+ description: string;
67
+ };
68
+ };
69
+ };
70
+ };
71
+ '/roles/{roleName}/multiPortals:remove': {
72
+ post: {
73
+ tags: string[];
74
+ summary: string;
75
+ description: string;
76
+ parameters: {
77
+ $ref: string;
78
+ }[];
79
+ requestBody: {
80
+ required: boolean;
81
+ content: {
82
+ 'application/json': {
83
+ schema: {
84
+ $ref: string;
85
+ };
86
+ };
87
+ };
88
+ };
89
+ responses: {
90
+ 200: {
91
+ description: string;
92
+ };
93
+ };
94
+ };
95
+ };
96
+ };
97
+ components: {
98
+ parameters: {
99
+ RoleNamePath: {
100
+ name: string;
101
+ in: string;
102
+ description: string;
103
+ required: boolean;
104
+ schema: {
105
+ type: string;
106
+ };
107
+ };
108
+ };
109
+ schemas: {
110
+ PortalAccessWrite: {
111
+ type: string;
112
+ properties: {
113
+ values: {
114
+ type: string;
115
+ description: string;
116
+ items: {
117
+ type: string;
118
+ };
119
+ minItems: number;
120
+ uniqueItems: boolean;
121
+ };
122
+ };
123
+ required: string[];
124
+ };
125
+ PortalAccessTarget: {
126
+ type: string;
127
+ additionalProperties: boolean;
128
+ properties: {
129
+ uid: {
130
+ type: string;
131
+ };
132
+ title: {
133
+ type: string;
134
+ };
135
+ portalName: {
136
+ type: string;
137
+ };
138
+ routePath: {
139
+ type: string;
140
+ };
141
+ portalType: {
142
+ type: string;
143
+ };
144
+ enabled: {
145
+ type: string;
146
+ };
147
+ };
148
+ };
149
+ };
150
+ };
151
+ };
152
+ export default _default;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var swagger_exports = {};
28
+ __export(swagger_exports, {
29
+ default: () => swagger_default
30
+ });
31
+ module.exports = __toCommonJS(swagger_exports);
32
+ var swagger_default = {
33
+ openapi: "3.0.2",
34
+ info: {
35
+ title: "NocoBase API - Multi-portal plugin",
36
+ version: "1.0.0"
37
+ },
38
+ paths: {
39
+ "/roles/{roleName}/multiPortals:list": {
40
+ get: {
41
+ tags: ["roles.multiPortals"],
42
+ summary: "List Portals granted to a role",
43
+ description: "List existing custom Portals that the role is explicitly allowed to enter.",
44
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }],
45
+ responses: {
46
+ 200: {
47
+ description: "OK",
48
+ content: {
49
+ "application/json": {
50
+ schema: {
51
+ type: "object",
52
+ properties: {
53
+ data: {
54
+ type: "array",
55
+ items: { $ref: "#/components/schemas/PortalAccessTarget" }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ },
65
+ "/roles/{roleName}/multiPortals:add": {
66
+ post: {
67
+ tags: ["roles.multiPortals"],
68
+ summary: "Grant Portal entry access to a role",
69
+ description: "Allow the role to enter one or more existing custom Portals by uid.",
70
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }],
71
+ requestBody: {
72
+ required: true,
73
+ content: {
74
+ "application/json": {
75
+ schema: { $ref: "#/components/schemas/PortalAccessWrite" }
76
+ }
77
+ }
78
+ },
79
+ responses: {
80
+ 200: { description: "OK" }
81
+ }
82
+ }
83
+ },
84
+ "/roles/{roleName}/multiPortals:remove": {
85
+ post: {
86
+ tags: ["roles.multiPortals"],
87
+ summary: "Revoke Portal entry access from a role",
88
+ description: "Prevent the role from entering one or more existing custom Portals by uid.",
89
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }],
90
+ requestBody: {
91
+ required: true,
92
+ content: {
93
+ "application/json": {
94
+ schema: { $ref: "#/components/schemas/PortalAccessWrite" }
95
+ }
96
+ }
97
+ },
98
+ responses: {
99
+ 200: { description: "OK" }
100
+ }
101
+ }
102
+ }
103
+ },
104
+ components: {
105
+ parameters: {
106
+ RoleNamePath: {
107
+ name: "roleName",
108
+ in: "path",
109
+ description: "Role name.",
110
+ required: true,
111
+ schema: { type: "string" }
112
+ }
113
+ },
114
+ schemas: {
115
+ PortalAccessWrite: {
116
+ type: "object",
117
+ properties: {
118
+ values: {
119
+ type: "array",
120
+ description: "Portal uids.",
121
+ items: { type: "string" },
122
+ minItems: 1,
123
+ uniqueItems: true
124
+ }
125
+ },
126
+ required: ["values"]
127
+ },
128
+ PortalAccessTarget: {
129
+ type: "object",
130
+ additionalProperties: true,
131
+ properties: {
132
+ uid: { type: "string" },
133
+ title: { type: "string" },
134
+ portalName: { type: "string" },
135
+ routePath: { type: "string" },
136
+ portalType: { type: "string" },
137
+ enabled: { type: "boolean" }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/plugin-multi-portal",
3
- "version": "3.0.0-alpha.2",
3
+ "version": "3.0.0-alpha.3",
4
4
  "main": "dist/server/index.js",
5
5
  "nocobase": {
6
6
  "supportedVersions": [
@@ -13,7 +13,7 @@
13
13
  "description.zh-CN": "为 Client V2 提供内置 Portal 注册、入口访问与路由权限管理。",
14
14
  "devDependencies": {
15
15
  "@ant-design/icons": "5.x",
16
- "@nocobase/plugin-ui-layout": "3.0.0-alpha.2",
16
+ "@nocobase/plugin-ui-layout": "3.0.0-alpha.3",
17
17
  "ahooks": "3.x",
18
18
  "antd": "5.x",
19
19
  "react": "^18.2.0",
@@ -29,5 +29,5 @@
29
29
  "@nocobase/server": "2.x",
30
30
  "@nocobase/test": "2.x"
31
31
  },
32
- "gitHead": "a3faea21082b30989301de04591ee1b91fd4e6a5"
32
+ "gitHead": "9899cd799c070c7bd85140148ea5b100b046bdc7"
33
33
  }