@lessly/sdk-app 63.2.3 → 63.2.4

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.
@@ -190,7 +190,11 @@ accessReason(app.mail.domain.create);
190
190
  ```
191
191
 
192
192
  Use it in every example below; nothing in an App should assemble this text by
193
- hand.
193
+ hand. It never throws and never renders the word `undefined`: an object with a
194
+ key but no usable level degrades to the key-only sentence, and an input with no
195
+ usable key at all falls back to `"Not available for your role. Ask an admin of
196
+ this product."` (plus one `console.warn` outside production, because that input
197
+ is a caller bug).
194
198
 
195
199
  It takes **one** operation. Choosing which operation to explain — the first one
196
200
  `can()` denied, out of the several a button performs — is the caller's job, and
@@ -227,11 +231,26 @@ exactly what the gateway does with an uncatalogued key.
227
231
  >
228
232
  > ```ts
229
233
  > import type { Operation } from '@lessly/sdk-app';
230
- > export const accessReason = (op: Operation | string): string =>
231
- > typeof op === 'string'
232
- > ? `Requires access to ${op}. Ask an admin of this product.`
233
- > : `Requires level:${op.level} (${op.operationKey}). Ask an admin of this product.`;
234
+ >
235
+ > const ok = (v: unknown): v is string => typeof v === 'string' && v.trim() !== '';
236
+ >
237
+ > export const accessReason = (op: Operation | string): string => {
238
+ > if (ok(op)) return `Requires access to ${op}. Ask an admin of this product.`;
239
+ > // A generated method is a CALLABLE carrying operationKey/level, so not just 'object'.
240
+ > if (op !== null && (typeof op === 'object' || typeof op === 'function')) {
241
+ > const { operationKey, level } = op as { operationKey?: unknown; level?: unknown };
242
+ > if (ok(operationKey)) {
243
+ > return ok(level) && ['read', 'write', 'admin'].includes(level)
244
+ > ? `Requires level:${level} (${operationKey}). Ask an admin of this product.`
245
+ > : `Requires access to ${operationKey}. Ask an admin of this product.`;
246
+ > }
247
+ > }
248
+ > return 'Not available for your role. Ask an admin of this product.';
249
+ > };
234
250
  > ```
251
+ >
252
+ > It never throws — a render helper that crashes takes the whole screen with it —
253
+ > and never renders `level:undefined`.
235
254
 
236
255
  **Why both values.** The reason says what an admin has to *grant*, not what the
237
256
  caller happens to be — a role name gives them nothing to act on, and "your role
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessly/sdk-app",
3
- "version": "63.2.3",
3
+ "version": "63.2.4",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "engines": {