@prsm/entitle 2.1.2 → 2.2.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.
package/README.md CHANGED
@@ -175,6 +175,10 @@ Returns the subject's effective plan name.
175
175
 
176
176
  Returns the full effective snapshot `{ plan, features, limits }`, for a settings or billing page.
177
177
 
178
+ ### `entitlements.catalog()`
179
+
180
+ Returns the static configuration `{ defaultPlan, plans, features, limits }`: every declared plan, the default plan, and the full feature and limit universes. Where `describe` resolves a single subject, `catalog` exposes the whole offering, for a plan comparison table, an admin dashboard, or documenting what the system grants. Subject-independent and read-only, so it never touches storage. The returned object is a fresh copy.
181
+
178
182
  ### `entitlements.close()`
179
183
 
180
184
  Releases driver resources.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prsm/entitle",
3
- "version": "2.1.2",
3
+ "version": "2.2.0",
4
4
  "description": "Plan-based entitlements and feature gating, resolved at runtime, backed by postgres",
5
5
  "type": "module",
6
6
  "exports": {
@@ -34,6 +34,14 @@ import ms from "@prsm/ms"
34
34
  * @property {Record<string, number|null>} limits - the resolved limit ceilings, after applying the subject's override on top of the plan (`null` means unlimited)
35
35
  */
36
36
 
37
+ /**
38
+ * @typedef {Object} Catalog
39
+ * @property {string} defaultPlan - the plan applied to a subject with no assignment
40
+ * @property {Record<string, Plan>} plans - the declared plan catalog (your pricing tiers)
41
+ * @property {string[]} features - the full feature universe (declared, or derived from the union across plans)
42
+ * @property {string[]} limits - the full limit universe (declared, or derived from the union across plans)
43
+ */
44
+
37
45
  /**
38
46
  * @typedef {Object} CheckResult
39
47
  * @property {boolean} allowed - whether current usage is below the limit (always true when the limit is unlimited)
@@ -200,6 +208,29 @@ export function createEntitlements(options = {}) {
200
208
  return driver.setup()
201
209
  },
202
210
 
211
+ /**
212
+ * The static configuration of this resolver: the plan catalog, the default
213
+ * plan, and the full feature and limit universes. Unlike describe(), which
214
+ * resolves a single subject, this exposes every plan and every declared key
215
+ * - for plan comparison tables, admin dashboards, or documenting what the
216
+ * system offers. Subject-independent, so it never touches storage. The
217
+ * returned object is a fresh copy; mutating it does not affect the resolver.
218
+ * @returns {Catalog}
219
+ */
220
+ catalog() {
221
+ return {
222
+ defaultPlan,
223
+ plans: Object.fromEntries(
224
+ Object.entries(catalog).map(([name, p]) => [name, {
225
+ features: { ...(p.features ?? {}) },
226
+ limits: { ...(p.limits ?? {}) },
227
+ }]),
228
+ ),
229
+ features: [...featureUniverse],
230
+ limits: [...limitUniverse],
231
+ }
232
+ },
233
+
203
234
  /**
204
235
  * Assign a subject to a plan. Takes effect immediately.
205
236
  * @param {string} subject - the subject identifier (whatever id you key entitlements by, such as an account or user id)
@@ -9,6 +9,16 @@
9
9
  export function createEntitlements(options?: EntitlementsOptions): {
10
10
  /** Create the backing tables if they do not exist. Idempotent. */
11
11
  setup(): any;
12
+ /**
13
+ * The static configuration of this resolver: the plan catalog, the default
14
+ * plan, and the full feature and limit universes. Unlike describe(), which
15
+ * resolves a single subject, this exposes every plan and every declared key
16
+ * - for plan comparison tables, admin dashboards, or documenting what the
17
+ * system offers. Subject-independent, so it never touches storage. The
18
+ * returned object is a fresh copy; mutating it does not affect the resolver.
19
+ * @returns {Catalog}
20
+ */
21
+ catalog(): Catalog;
12
22
  /**
13
23
  * Assign a subject to a plan. Takes effect immediately.
14
24
  * @param {string} subject - the subject identifier (whatever id you key entitlements by, such as an account or user id)
@@ -169,6 +179,24 @@ export type Effective = {
169
179
  */
170
180
  limits: Record<string, number | null>;
171
181
  };
182
+ export type Catalog = {
183
+ /**
184
+ * - the plan applied to a subject with no assignment
185
+ */
186
+ defaultPlan: string;
187
+ /**
188
+ * - the declared plan catalog (your pricing tiers)
189
+ */
190
+ plans: Record<string, Plan>;
191
+ /**
192
+ * - the full feature universe (declared, or derived from the union across plans)
193
+ */
194
+ features: string[];
195
+ /**
196
+ * - the full limit universe (declared, or derived from the union across plans)
197
+ */
198
+ limits: string[];
199
+ };
172
200
  export type CheckResult = {
173
201
  /**
174
202
  * - whether current usage is below the limit (always true when the limit is unlimited)