mnfst 0.5.143 → 0.5.145

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.
@@ -108,6 +108,20 @@ async function getAppwriteConfig() {
108
108
  // Creator role: string reference to a role in memberRoles (role creator gets by default)
109
109
  const creatorRole = appwriteConfig.auth?.creatorRole || null;
110
110
 
111
+ // Creator roles (plural): the custom role(s) the team creator is assigned, atomically,
112
+ // at team creation. Accepts string | string[] | null. An explicit null / [] means
113
+ // "no template role — creator holds only Appwrite's intrinsic owner". Takes precedence
114
+ // over the legacy singular `creatorRole`. When NEITHER is set, createTeam keeps its
115
+ // historical default (first defined role). Resolved to: array (configured, [] = owner-only)
116
+ // or null (unconfigured → use the historical default).
117
+ let creatorRoles = null;
118
+ if (appwriteConfig.auth && Object.prototype.hasOwnProperty.call(appwriteConfig.auth, 'creatorRoles')) {
119
+ const raw = appwriteConfig.auth.creatorRoles;
120
+ creatorRoles = raw == null ? [] : (Array.isArray(raw) ? raw.filter(r => typeof r === 'string') : [raw]).filter(Boolean);
121
+ } else if (creatorRole && memberRoles && memberRoles[creatorRole]) {
122
+ creatorRoles = [creatorRole];
123
+ }
124
+
111
125
  // Guest migration: id of the deployed guest-migration Appwrite Function. When set,
112
126
  // a guest's teams are carried over to the account they sign into via OTP (which
113
127
  // Appwrite can't convert in place). See templates/guest-migration-function.
@@ -135,7 +149,8 @@ async function getAppwriteConfig() {
135
149
  memberRoles: memberRoles, // Role definitions: { "RoleName": ["permission1", "permission2"] }
136
150
  permanentRoles: permanentRoles, // Object: { "RoleName": ["permission1", ...] } (cannot be deleted)
137
151
  templateRoles: templateRoles, // Object: { "RoleName": ["permission1", ...] } (can be deleted)
138
- creatorRole: creatorRole // String reference to memberRoles key
152
+ creatorRole: creatorRole, // String reference to memberRoles key (legacy singular)
153
+ creatorRoles: creatorRoles // array (configured; [] = owner-only) or null (use historical default)
139
154
  };
140
155
  }
141
156
 
@@ -1402,13 +1417,14 @@ function initializeTeamsCore() {
1402
1417
  // Determine initial roles for team creator
1403
1418
  let creatorRoles = roles;
1404
1419
  if (creatorRoles.length === 0) {
1405
- // If no roles specified, use creatorRole from config
1406
1420
  const memberRoles = appwriteConfig?.memberRoles;
1407
- const creatorRoleName = appwriteConfig?.creatorRole;
1421
+ const configuredCreatorRoles = appwriteConfig?.creatorRoles; // array | null
1408
1422
 
1409
- if (memberRoles && creatorRoleName && memberRoles[creatorRoleName]) {
1410
- // Use specified creatorRole
1411
- creatorRoles = [creatorRoleName];
1423
+ if (Array.isArray(configuredCreatorRoles)) {
1424
+ // Explicitly configured via auth.creatorRoles (or legacy creatorRole).
1425
+ // An empty array means "owner-only" — the creator holds just
1426
+ // Appwrite's intrinsic owner, with no template role assigned.
1427
+ creatorRoles = configuredCreatorRoles.length ? configuredCreatorRoles.slice() : ['owner'];
1412
1428
  } else if (memberRoles && Object.keys(memberRoles).length > 0) {
1413
1429
  // No creatorRole specified, find role with all owner permissions or use first
1414
1430
  let foundRole = null;
@@ -5525,29 +5541,43 @@ function initializeTeamsConvenience() {
5525
5541
  return userRoles.includes('owner');
5526
5542
  };
5527
5543
 
5528
- // Synchronous version for Alpine.js bindings (uses permission cache)
5544
+ // Synchronous version for Alpine.js bindings (x-show / :disabled).
5545
+ // Resolves from the cached role definitions (allTeamRoles) so it matches
5546
+ // the async hasTeamPermission() — including custom permission keys, not
5547
+ // just the six built-ins the permission cache pre-computes.
5529
5548
  store.hasTeamPermissionSync = function (permission) {
5530
5549
  if (!this.currentTeam || !this.currentTeamMemberships || !this.user) {
5531
5550
  return false;
5532
5551
  }
5533
5552
 
5534
- // Use cached permissions if available (updated by updatePermissionCache)
5535
- if (this._permissionCache && typeof this._permissionCache[permission] === 'boolean') {
5536
- return this._permissionCache[permission];
5553
+ const userRoles = this.getCurrentTeamRoles();
5554
+ if (!Array.isArray(userRoles)) {
5555
+ return false;
5537
5556
  }
5538
5557
 
5539
- // Fallback: check if user has no custom roles (should have all permissions)
5540
- // This matches the logic in hasPermission: if customRoles.length === 0, return true
5541
- const userRoles = this.getCurrentTeamRoles();
5542
- const customRoles = userRoles.filter(role => role !== 'owner');
5558
+ // The merged config + user-generated role map for the current team
5559
+ // (same map the async path resolves against), available synchronously.
5560
+ const allRoles = (this.allTeamRoles && this.allTeamRoles(this.currentTeam)) || {};
5543
5561
 
5544
- // If user has no custom roles (only "owner" or empty), grant all permissions
5545
- // This handles users with "No Role" who should have all owner permissions
5562
+ // No custom roles defined owner has every permission.
5563
+ if (!allRoles || Object.keys(allRoles).length === 0) {
5564
+ return userRoles.includes('owner');
5565
+ }
5566
+
5567
+ // User holds no custom role (only "owner" / empty) → all permissions.
5568
+ const customRoles = userRoles.filter(role => role !== 'owner');
5546
5569
  if (customRoles.length === 0) {
5547
5570
  return true;
5548
5571
  }
5549
5572
 
5550
- // If user has custom roles but cache is missing, return false (shouldn't happen if cache is working)
5573
+ // Granted if any of the user's custom roles includes this permission
5574
+ // (built-in or custom key).
5575
+ for (const roleName of customRoles) {
5576
+ const rolePermissions = allRoles[roleName];
5577
+ if (Array.isArray(rolePermissions) && rolePermissions.includes(permission)) {
5578
+ return true;
5579
+ }
5580
+ }
5551
5581
  return false;
5552
5582
  };
5553
5583
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "manifest.appwrite.auth.js": "sha384-9XC7lR7xBSDktRSQ2OVjcDOZ5NT3IPzdfmGO3Rv4x37uAvrzfi20xER0Renn5MTj",
2
+ "manifest.appwrite.auth.js": "sha384-1Kz/Dlerds1/7iKrEVDIRbFDyngZ0L+f81td9eW3w4t3nGFU+w4gjyGhwn+IiTRM",
3
3
  "manifest.appwrite.data.js": "sha384-00ulLT+GAIuPHA/rRT9p98vYlsyDzkyKXtg86BDQ6FGQa5vVVN+W6kuforniBAsz",
4
4
  "manifest.appwrite.presence.js": "sha384-uxRpx9/Jj0kGtklH5QmUlAzD3zdSvFRfK6bcJQqxl+Bsf5tOo4zgwqJTQgtZoHQP",
5
5
  "manifest.charts.js": "sha384-RuV7gWXt3s+JegxWgDieR/P5U99sbOYWiYHdJGe2uCJjDFU1cPp0mJ1QT55ec9uz",
@@ -197,7 +197,15 @@
197
197
  }
198
198
  }
199
199
  },
200
- "creatorRole": { "type": "string" }
200
+ "creatorRole": { "type": "string" },
201
+ "creatorRoles": {
202
+ "description": "Role(s) the team creator is assigned atomically at creation. null or [] = owner-only (creator holds just Appwrite's intrinsic owner; no template role). Takes precedence over creatorRole.",
203
+ "oneOf": [
204
+ { "type": "string" },
205
+ { "type": "array", "items": { "type": "string" } },
206
+ { "type": "null" }
207
+ ]
208
+ }
201
209
  }
202
210
  }
203
211
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.143",
3
+ "version": "0.5.145",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",