@makolabs/ripple 1.7.1 → 1.7.2

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.
@@ -176,6 +176,10 @@ export async function getUserPermissions(userId) {
176
176
  export async function updateUserPermissions(options) {
177
177
  await delay();
178
178
  const { userId, permissions } = options;
179
+ // Validate permissions - require at least one permission scope
180
+ if (permissions.length === 0) {
181
+ throw new Error('At least one permission scope is required');
182
+ }
179
183
  const user = mockUsers.find((u) => u.id === userId);
180
184
  if (!user) {
181
185
  throw new Error(`User with ID ${userId} not found`);
@@ -188,6 +192,10 @@ export async function updateUserPermissions(options) {
188
192
  */
189
193
  export async function generateApiKey(options) {
190
194
  await delay();
195
+ // Validate permissions - require at least one permission scope
196
+ if (options.permissions.length === 0) {
197
+ throw new Error('At least one permission scope is required');
198
+ }
191
199
  const { userId } = options;
192
200
  const user = mockUsers.find((u) => u.id === userId);
193
201
  if (!user) {
@@ -416,6 +416,10 @@ async function refreshTokenIfSelfUpdate(userId) {
416
416
  export const updateUserPermissions = command('unchecked', async (options) => {
417
417
  const { userId, permissions } = options;
418
418
  try {
419
+ // Validate permissions - require at least one permission scope
420
+ if (permissions.length === 0) {
421
+ throw new Error('At least one permission scope is required');
422
+ }
419
423
  // Fetch user's active keys
420
424
  const allKeysData = await makeAdminRequest(`/admin/keys?client_id=${CLIENT_ID}&sub=${userId}`);
421
425
  const userKeys = (allKeysData?.data?.data || []).filter((key) => key.status === 'active');
@@ -455,7 +459,9 @@ export const updateUserPermissions = command('unchecked', async (options) => {
455
459
  console.log('[updateUserPermissions] Key verification:', verification);
456
460
  if (verification.valid) {
457
461
  // Check if the scopes match what we expect
458
- const scopesMatch = permissions.every((perm) => verification.scopes?.includes(perm));
462
+ // Note: permissions.length > 0 is guaranteed by validation above
463
+ const scopesMatch = permissions.length > 0 &&
464
+ permissions.every((perm) => verification.scopes?.includes(perm));
459
465
  if (!scopesMatch) {
460
466
  console.warn('[updateUserPermissions] Scopes mismatch. Expected:', permissions, 'Got:', verification.scopes);
461
467
  }
package/dist/index.d.ts CHANGED
@@ -339,6 +339,10 @@ export interface NavItemProps {
339
339
  export interface SidebarProps {
340
340
  items?: NavigationItem[];
341
341
  logo: LogoType;
342
+ /** Optional footer snippet rendered at the bottom of the sidebar */
343
+ footer?: Snippet<[{
344
+ collapsed: boolean;
345
+ }]>;
342
346
  }
343
347
  export { tv, cn } from './helper/cls.js';
344
348
  export { isRouteActive } from './helper/nav.svelte.js';
@@ -5,7 +5,7 @@
5
5
  import { isRouteActive } from '../../helper/nav.svelte.js';
6
6
  import { resolve } from '$app/paths';
7
7
 
8
- let { items = [], logo }: SidebarProps = $props();
8
+ let { items = [], logo, footer }: SidebarProps = $props();
9
9
  let menubar: MenuBar = $state({
10
10
  collapsed: false
11
11
  });
@@ -178,6 +178,13 @@
178
178
  {/each}
179
179
  </nav>
180
180
  </div>
181
+
182
+ <!-- Footer slot for custom content -->
183
+ {#if footer}
184
+ <div class="shrink-0 border-t border-white/10 px-3 py-3">
185
+ {@render footer({ collapsed: menubar.collapsed })}
186
+ </div>
187
+ {/if}
181
188
  </div>
182
189
 
183
190
  {#snippet ToggleIcon(classes = 'size-6 shrink-0 text-default-200')}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makolabs/ripple",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "description": "Simple Svelte 5 powered component library ✨",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {