@cfast/permissions 0.5.1 → 0.6.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.
@@ -420,4 +420,4 @@ declare class PermissionRegistrationError extends Error {
420
420
  constructor(subject: string, availableTables: readonly string[]);
421
421
  }
422
422
 
423
- export { CRUD_ACTIONS as C, type DrizzleTable as D, ForbiddenError as F, type Grant as G, type LookupDb as L, type PermissionsConfig as P, type SchemaMap as S, type TableName as T, type WithLookups as W, type Permissions as a, type PermissionAction as b, type SubjectInput as c, type WhereClause as d, type PermissionDescriptor as e, type PermissionCheckResult as f, type ColumnsOf as g, type CrudAction as h, type GrantFn as i, type LookupFn as j, PermissionRegistrationError as k, type SqlNameOf as l, getTableName as m };
423
+ export { type CrudAction as C, type DrizzleTable as D, ForbiddenError as F, type Grant as G, type LookupDb as L, type PermissionsConfig as P, type SchemaMap as S, type TableName as T, type WithLookups as W, type Permissions as a, type PermissionAction as b, type SubjectInput as c, type WhereClause as d, type PermissionDescriptor as e, type PermissionCheckResult as f, CRUD_ACTIONS as g, type ColumnsOf as h, type GrantFn as i, type LookupFn as j, PermissionRegistrationError as k, type SqlNameOf as l, getTableName as m };
package/dist/client.d.ts CHANGED
@@ -1 +1 @@
1
- export { h as CrudAction, F as ForbiddenError, b as PermissionAction, f as PermissionCheckResult, e as PermissionDescriptor } from './client-DpwiMpD0.js';
1
+ export { C as CrudAction, F as ForbiddenError, b as PermissionAction, f as PermissionCheckResult, e as PermissionDescriptor } from './client-DyadVgmx.js';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PermissionsConfig, a as Permissions, S as SchemaMap, b as PermissionAction, c as SubjectInput, W as WithLookups, d as WhereClause, G as Grant, e as PermissionDescriptor, f as PermissionCheckResult } from './client-DpwiMpD0.js';
2
- export { C as CRUD_ACTIONS, g as ColumnsOf, h as CrudAction, D as DrizzleTable, F as ForbiddenError, i as GrantFn, L as LookupDb, j as LookupFn, k as PermissionRegistrationError, l as SqlNameOf, T as TableName, m as getTableName } from './client-DpwiMpD0.js';
1
+ import { P as PermissionsConfig, a as Permissions, S as SchemaMap, b as PermissionAction, c as SubjectInput, W as WithLookups, d as WhereClause, G as Grant, e as PermissionDescriptor, f as PermissionCheckResult, C as CrudAction, D as DrizzleTable } from './client-DyadVgmx.js';
2
+ export { g as CRUD_ACTIONS, h as ColumnsOf, F as ForbiddenError, i as GrantFn, L as LookupDb, j as LookupFn, k as PermissionRegistrationError, l as SqlNameOf, T as TableName, m as getTableName } from './client-DyadVgmx.js';
3
3
 
4
4
  /**
5
5
  * Creates a permission configuration that can be shared between server-side
@@ -263,4 +263,33 @@ type UserWithRoles = {
263
263
  declare function resolveGrants(permissions: Permissions, user: UserWithRoles): Grant[];
264
264
  declare function resolveGrants(permissions: Permissions, roles: readonly string[]): Grant[];
265
265
 
266
- export { Grant, PermissionAction, PermissionCheckResult, PermissionDescriptor, Permissions, PermissionsConfig, SchemaMap, SubjectInput, type UserWithRoles, WhereClause, WithLookups, can, checkPermissions, definePermissions, grant, resolveGrants };
266
+ /**
267
+ * A single granted action for a table, including the matching grants.
268
+ *
269
+ * - `unrestricted: true` means at least one grant has no `where` clause,
270
+ * so the action is unconditionally permitted for every row.
271
+ * - `unrestricted: false` means all matching grants have `where` clauses,
272
+ * so whether the action is permitted depends on the specific row.
273
+ */
274
+ type GrantedAction = {
275
+ action: CrudAction;
276
+ grants: Grant[];
277
+ unrestricted: boolean;
278
+ };
279
+ /**
280
+ * Returns the distinct CRUD actions that are granted for a given table.
281
+ *
282
+ * `manage` grants are expanded into the four CRUD actions. For each action,
283
+ * the result includes the matching grants and whether any of them is
284
+ * unrestricted (no `where` clause). Actions with no matching grant at all
285
+ * are excluded from the result.
286
+ *
287
+ * Used by `@cfast/db` to build `_can` annotations on query results.
288
+ *
289
+ * @param grants - The user's resolved permission grants.
290
+ * @param table - The Drizzle table to check grants against.
291
+ * @returns Array of GrantedAction objects for each permitted action.
292
+ */
293
+ declare function getGrantedActions(grants: Grant[], table: DrizzleTable): GrantedAction[];
294
+
295
+ export { CrudAction, DrizzleTable, Grant, type GrantedAction, PermissionAction, PermissionCheckResult, PermissionDescriptor, Permissions, PermissionsConfig, SchemaMap, SubjectInput, type UserWithRoles, WhereClause, WithLookups, can, checkPermissions, definePermissions, getGrantedActions, grant, resolveGrants };
package/dist/index.js CHANGED
@@ -234,6 +234,25 @@ function resolveGrants(permissions, userOrRoles) {
234
234
  }
235
235
  return result;
236
236
  }
237
+
238
+ // src/granted-actions.ts
239
+ function getGrantedActions(grants, table) {
240
+ const targetName = getTableName(table);
241
+ const result = [];
242
+ for (const action of CRUD_ACTIONS) {
243
+ const matching = grants.filter((g) => {
244
+ const actionOk = g.action === action || g.action === "manage";
245
+ if (!actionOk) return false;
246
+ if (g.subject === "all") return true;
247
+ if (g.subject === table) return true;
248
+ return getTableName(g.subject) === targetName;
249
+ });
250
+ if (matching.length === 0) continue;
251
+ const unrestricted = matching.some((g) => !g.where);
252
+ result.push({ action, grants: matching, unrestricted });
253
+ }
254
+ return result;
255
+ }
237
256
  export {
238
257
  CRUD_ACTIONS,
239
258
  ForbiddenError,
@@ -241,6 +260,7 @@ export {
241
260
  can,
242
261
  checkPermissions,
243
262
  definePermissions,
263
+ getGrantedActions,
244
264
  getTableName,
245
265
  grant,
246
266
  resolveGrants
package/llms.txt CHANGED
@@ -209,6 +209,21 @@ can<typeof schema>(grants, "create", "posts") // ✓ string form, type-ch
209
209
  // can<typeof schema>(grants, "create", "unknownTable") // ✗ TypeScript error
210
210
  ```
211
211
 
212
+ ### `getGrantedActions(grants, table): GrantedAction[]`
213
+ ```typescript
214
+ import { getGrantedActions } from "@cfast/permissions";
215
+ function getGrantedActions(grants: Grant[], table: DrizzleTable): GrantedAction[]
216
+
217
+ type GrantedAction = {
218
+ action: CrudAction; // "read" | "create" | "update" | "delete"
219
+ grants: Grant[]; // the matching grants
220
+ unrestricted: boolean; // true if any grant has no `where` clause
221
+ };
222
+ ```
223
+ Returns the distinct CRUD actions that are granted for a given table. `manage` grants are expanded into the four CRUD actions. For each action, the result includes the matching grants and whether any of them is unrestricted (no `where` clause). Actions with no matching grant are excluded.
224
+
225
+ Used internally by `@cfast/db` to build row-level `_can` annotations on query results.
226
+
212
227
  ### `CRUD_ACTIONS`
213
228
  ```typescript
214
229
  const CRUD_ACTIONS: readonly CrudAction[] = ["read", "create", "update", "delete"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfast/permissions",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Isomorphic, composable permission system with Drizzle-native row-level access control",
5
5
  "keywords": [
6
6
  "cfast",