@easy-cms/plugin-multi-tenant 0.65.0 → 0.66.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +57 -3
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ var INFO = {
62
62
  name: "@easy-cms/plugin-multi-tenant",
63
63
  // The plugin API it is written for (`PLUGIN_API_VERSION` of @easy-cms/core).
64
64
  apiVersion: 1,
65
- ...true ? { version: "0.65.0" } : {}
65
+ ...true ? { version: "0.66.1" } : {}
66
66
  };
67
67
 
68
68
  // src/members.ts
@@ -234,6 +234,23 @@ function membersEndpoints(options) {
234
234
  }
235
235
 
236
236
  // src/plugin.ts
237
+ var PLUGIN_GROUPS = [
238
+ { plugin: "formBuilderPlugin", slugs: ["forms", "form-submissions"] },
239
+ {
240
+ plugin: "ecommercePlugin",
241
+ slugs: [
242
+ "products",
243
+ "variant-types",
244
+ "variant-options",
245
+ "variants",
246
+ "carts",
247
+ "addresses",
248
+ "orders",
249
+ "transactions",
250
+ "shop-counters"
251
+ ]
252
+ }
253
+ ];
237
254
  var BUILTIN_ACCESS = {
238
255
  [MEDIA]: { read: () => true, create: isStaff, update: isStaff, delete: isStaff },
239
256
  [MEDIA_FOLDERS]: { read: isStaff, create: isStaff, update: isStaff, delete: isStaff }
@@ -266,6 +283,15 @@ function multiTenantPlugin(options) {
266
283
  );
267
284
  if (scoped.has(tenantsSlug) || scoped.has("users"))
268
285
  throw new Error(`multiTenantPlugin: "${tenantsSlug}" and "users" can't belong to a tenant`);
286
+ const partly = PLUGIN_GROUPS.flatMap(({ plugin, slugs }) => {
287
+ const present = slugs.filter((slug) => declared.has(slug));
288
+ const listed = present.filter((slug) => scoped.has(slug));
289
+ const shared = present.filter((slug) => !scoped.has(slug));
290
+ return listed.length > 0 && shared.length > 0 ? [
291
+ `multiTenantPlugin: ${shared.map((x) => `"${x}"`).join(", ")} of ${plugin} are shared by all tenants while ${listed.map((x) => `"${x}"`).join(", ")} belong to one; list them all in \`collections\`, or none`
292
+ ] : [];
293
+ });
294
+ let warned = partly.length === 0;
269
295
  const perTenant = new Set(options.globals ?? []);
270
296
  const unknownGlobals = [...perTenant].filter(
271
297
  (g) => !(config.globals ?? []).some((global) => global.slug === g)
@@ -439,6 +465,23 @@ function multiTenantPlugin(options) {
439
465
  delete: and(custom?.delete, ({ user, context }) => superUser(user, context))
440
466
  };
441
467
  };
468
+ const ownMemberships = ({ doc, user, context }) => {
469
+ if (!user || superUser(user, context) || sameId(doc.id, user.id)) return doc;
470
+ const list = doc[MEMBERSHIPS_FIELD];
471
+ if (!Array.isArray(list)) return doc;
472
+ const { tenant } = tenantOf(context);
473
+ const idOf = (value) => typeof value === "object" && value !== null ? value.id : value;
474
+ return {
475
+ ...doc,
476
+ [MEMBERSHIPS_FIELD]: list.filter(
477
+ (m) => tenant !== null && sameId(idOf(m.tenant), tenant)
478
+ )
479
+ };
480
+ };
481
+ const usersHooks = (hooks = {}) => ({
482
+ ...hooks,
483
+ afterRead: [...hooks.afterRead ?? [], ownMemberships]
484
+ });
442
485
  const tenantsAccess = {
443
486
  read: ({ user, context }) => {
444
487
  if (!user) return false;
@@ -517,7 +560,8 @@ function multiTenantPlugin(options) {
517
560
  collections.push({
518
561
  ...c,
519
562
  fields: [...withTenantFilters(c.fields), memberships],
520
- access: { ...c.access, ...usersAccess(c.access) }
563
+ access: { ...c.access, ...usersAccess(c.access) },
564
+ hooks: usersHooks(c.hooks)
521
565
  });
522
566
  } else if (scoped.has(c.slug)) collections.push(scopeCollection(c, BUILTIN_ACCESS[c.slug]));
523
567
  else
@@ -532,7 +576,13 @@ function multiTenantPlugin(options) {
532
576
  }
533
577
  });
534
578
  }
535
- if (!hasUsers) collections.push({ slug: "users", fields: [memberships], access: usersAccess() });
579
+ if (!hasUsers)
580
+ collections.push({
581
+ slug: "users",
582
+ fields: [memberships],
583
+ access: usersAccess(),
584
+ hooks: usersHooks()
585
+ });
536
586
  for (const builtin of [MEDIA, MEDIA_FOLDERS]) {
537
587
  if (scoped.has(builtin) && !declared.has(builtin))
538
588
  collections.push(
@@ -564,6 +614,10 @@ function multiTenantPlugin(options) {
564
614
  });
565
615
  const previous = config.onRequest;
566
616
  const onRequest = async (args) => {
617
+ if (!warned) {
618
+ warned = true;
619
+ for (const message of partly) args.cms.logger.warn(message);
620
+ }
567
621
  const user = args.user;
568
622
  const list = await tenantList(args.cms, tenantsSlug);
569
623
  const asked = args.headers.get(header) ?? args.url?.searchParams.get("tenant") ?? readCookie(args.headers.get("cookie"), cookie) ?? null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-cms/plugin-multi-tenant",
3
- "version": "0.65.0",
3
+ "version": "0.66.1",
4
4
  "description": "Multi-tenant Easy CMS: several sites or clients in one CMS, each with its own content, members and roles",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,14 +17,14 @@
17
17
  "dist"
18
18
  ],
19
19
  "peerDependencies": {
20
- "@easy-cms/core": "^0.65.0"
20
+ "@easy-cms/core": "^0.66.1"
21
21
  },
22
22
  "devDependencies": {
23
- "@easy-cms/core": "^0.65.0",
24
- "@easy-cms/plugin-form-builder": "^0.65.0",
25
- "@easy-cms/db-sqlite": "^0.65.0",
26
- "@easy-cms/plugin-nested-docs": "^0.65.0",
27
- "@easy-cms/plugin-redirects": "^0.65.0"
23
+ "@easy-cms/core": "^0.66.1",
24
+ "@easy-cms/db-sqlite": "^0.66.1",
25
+ "@easy-cms/plugin-nested-docs": "^0.66.1",
26
+ "@easy-cms/plugin-redirects": "^0.66.1",
27
+ "@easy-cms/plugin-form-builder": "^0.66.1"
28
28
  },
29
29
  "engines": {
30
30
  "node": ">=22.12"