rune-lab 0.0.7 โ†’ 0.0.9

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.
Files changed (34) hide show
  1. package/README.md +38 -25
  2. package/dist/components/api/RLApiInterface.svelte +18 -12
  3. package/dist/components/api/RLApiInterface.svelte.d.ts +4 -6
  4. package/dist/components/common/RLPripertyTable.svelte +107 -0
  5. package/dist/components/common/RLPripertyTable.svelte.d.ts +44 -0
  6. package/dist/components/dataview/RLDetailRow.svelte +61 -0
  7. package/dist/components/dataview/RLDetailRow.svelte.d.ts +20 -0
  8. package/dist/components/dataview/RLMetadataList.svelte +53 -0
  9. package/dist/components/dataview/RLMetadataList.svelte.d.ts +23 -0
  10. package/dist/components/dataview/RLMetadataTable.svelte +1 -4
  11. package/dist/components/explorer/RLEnumDisplay.svelte +34 -0
  12. package/dist/components/explorer/RLEnumDisplay.svelte.d.ts +7 -0
  13. package/dist/components/explorer/RLFunctionDisplay.svelte +64 -0
  14. package/dist/components/explorer/RLFunctionDisplay.svelte.d.ts +13 -0
  15. package/dist/components/explorer/RLSchemaExplorer.svelte +204 -319
  16. package/dist/components/explorer/RLTableDisplay.svelte +48 -0
  17. package/dist/components/explorer/RLTableDisplay.svelte.d.ts +16 -0
  18. package/dist/components/explorer/RLViewDisplay.svelte +46 -0
  19. package/dist/components/explorer/RLViewDisplay.svelte.d.ts +15 -0
  20. package/dist/components/form/RLFilterForm.svelte +1 -13
  21. package/dist/components/form/RLFunctionForm.svelte +2 -13
  22. package/dist/components/form/RLResourceForm.svelte +1 -13
  23. package/dist/components/stores/explorer.svelte.d.ts +59 -0
  24. package/dist/mod.d.ts +2 -0
  25. package/dist/mod.js +2 -0
  26. package/dist/tools/form-helpers.d.ts +23 -0
  27. package/dist/tools/form-helpers.js +51 -0
  28. package/dist/tools/schema-transformer.d.ts +5 -0
  29. package/dist/tools/schema-transformer.js +131 -0
  30. package/dist/types/api.d.ts +1 -0
  31. package/dist/types/api.js +1 -0
  32. package/dist/types/explorer.d.ts +1 -0
  33. package/dist/types/explorer.js +1 -0
  34. package/package.json +2 -1
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <h1 align="center">
2
- <img src="https://raw.githubusercontent.com/Yrrrrrf/rune-lab/main/static/rune.png" alt="Rune Lab Icon" width="128" height="128" description="Some rune that represents the Svelte rune system">
2
+ <img src="https://raw.githubusercontent.com/Yrrrrrf/rune-lab/main/static/rune.png" alt="Rune Lab Icon" width="128" height="128" description="Icon representing the Svelte Runes system">
3
3
  <div align="center">Rune Lab</div>
4
4
  </h1>
5
5
 
@@ -14,48 +14,61 @@
14
14
 
15
15
  ## Overview
16
16
 
17
- Rune Lab is a modern component library built with Svelte 5, focused on providing powerful,
18
- reactive UI components using Svelte's runes system. It offers a comprehensive set of components,
19
- theming capabilities, and utilities for building modern web applications.
17
+ **Rune Lab** is your modern toolkit for crafting stunning, reactive web applications with
18
+ **Svelte 5**. Harnessing the power of Svelte's new **Runes** system, Rune Lab offers a suite of
19
+ elegant UI components designed for seamless data handling and beautiful theming.
20
20
 
21
- ## Features
21
+ It's built to integrate effortlessly with your data sources, especially shining when connected
22
+ to the [prism-py](https://github.com/Yrrrrrf/prism-py) and
23
+ [prism-ts](https://github.com/Yrrrrrf/prism-ts) ecosystem for end-to-end type-safe API
24
+ interactions.
22
25
 
23
- - **๐Ÿงช Svelte 5 Runes**: Built with Svelte 5's powerful reactivity primitives
24
- - **๐ŸŽจ Theme System**: Extensive theming with DaisyUI integration
25
- - **๐Ÿ”„ Type Safety**: Full TypeScript support with strong typing
26
- - **๐Ÿ“Š Data Visualization**: Components for visualizing complex data
27
- - **๐ŸŒ API Integration**: Tools for type-safe API interactions
28
- - **๐Ÿ“ฆ Zero Dependencies**: Lightweight core with optional integrations
29
- - **๐Ÿฆ• Deno & NPM**: Available on both JSR and NPM
26
+ ## Key Features
27
+
28
+ - **โœจ Svelte 5 Runes Core:** Experience fine-grained reactivity and cleaner component logic.
29
+ - **๐ŸŽจ Dynamic Theming:** Powered by DaisyUI & Tailwind CSS for extensive customization and
30
+ out-of-the-box themes.
31
+ - **๐Ÿ”’ TypeScript First:** Robust type-safety for a confident and productive development
32
+ workflow.
33
+ - **๐Ÿ“Š Data-Aware Components:** Tools and components built to handle and visualize complex data.
34
+ - **๐Ÿ›ฐ๏ธ Interactive Schema Explorer:** A standout feature! Visually explore and interact with
35
+ database schemas exposed by `prism-py` APIs directly within your Svelte application. Test CRUD
36
+ operations, execute functions, and understand your data structure like never before.
37
+ - **๐ŸŒ Smart API Integration:** Includes `apiStore` (using `prism-ts`) for easy and type-safe
38
+ connection to backend APIs.
39
+ - **๐Ÿ“ฆ Lightweight Core:** Designed to be lean, with optional integrations.
40
+ - **๐Ÿฆ• Universal Access:** Available on JSR (for Deno) and NPM (for Node.js/Bun/Yarn).
41
+
42
+ ## The Prism Ecosystem Advantage
43
+
44
+ Rune Lab is designed to be a perfect companion to the Prism ecosystem:
45
+
46
+ - **[prism-py](https://github.com/Yrrrrrf/prism-py):** Automatically generates REST APIs from
47
+ your database schema.
48
+ - **[prism-ts](https://github.com/Yrrrrrf/prism-ts):** A TypeScript client that consumes these
49
+ APIs with full type-safety.
50
+
51
+ When used together, Rune Lab's API integration tools (like the `apiStore` and
52
+ `RLSchemaExplorer`) provide a remarkably streamlined and type-safe path from your backend data
53
+ to your frontend UI.
30
54
 
31
55
  ## Installation
32
56
 
33
- ### Using Deno / JSR
57
+ ### Using Deno / [JSR](https://jsr.io/@yrrrrrf/rune-lab)
34
58
 
35
59
  ```bash
36
60
  # Add to your Deno project
37
61
  deno add @yrrrrrf/rune-lab
38
62
  ```
39
63
 
40
- ### Using NPM / Bun / Yarn
64
+ ### Using [NPM](https://www.npmjs.com/package/rune-lab) / Bun / Yarn
41
65
 
42
66
  ```bash
43
- # NPM
44
67
  npm install rune-lab
45
-
46
- # Bun
47
68
  bun add rune-lab
48
-
49
- # Yarn
50
69
  yarn add rune-lab
51
70
  ```
52
71
 
53
72
  ## License
54
73
 
55
74
  MIT License - See [LICENSE](LICENSE) for details.
56
-
57
- ---
58
-
59
- <div align="center">
60
- Built with โค๏ธ using Svelte 5 and Deno
61
- </div>
@@ -1,46 +1,52 @@
1
1
  <!-- src/lib/components/api/RLApiInterface.svelte -->
2
2
  <script lang="ts">
3
- import type { ColumnMetadata } from '@yrrrrrf/prism-ts';
4
- type APIOperation = 'GET' | 'POST' | 'PUT' | 'DELETE';
3
+ import type { ColumnMetadata as PrismColumnMetadata } from '@yrrrrrf/prism-ts';
4
+ // Import RLApiInterfaceActionParams from YOUR definition in the explorer store
5
+ import type { RLApiInterfaceActionParams } from '../stores/explorer.svelte.ts';
6
+
7
+ // For convenience within this component, you can extract the operation type.
8
+ // This is NOT redefining it; it's creating a local alias to a part of an imported type.
9
+ type LocalAPIOperation = RLApiInterfaceActionParams['operation'];
5
10
 
6
11
  let {
7
12
  schemaName,
8
13
  resourceName,
9
14
  resourceType,
10
15
  columns,
11
- onOpenModal // <-- ADDED THIS PROP
16
+ onOpenModal
12
17
  } = $props<{
13
18
  schemaName: string;
14
19
  resourceName: string;
15
- resourceType: 'table' | 'view' | 'function'; // Added 'function' for future
16
- columns: ColumnMetadata[]; // Still relevant for tables/views context
17
- onOpenModal: (params: { operation: APIOperation }) => void; // <-- TYPE FOR THE PROP
20
+ resourceType: 'table' | 'view' | 'function';
21
+ columns: PrismColumnMetadata[]; // This prop is fine if it's what the component receives
22
+ onOpenModal: (params: RLApiInterfaceActionParams) => void; // Uses your imported interface
18
23
  }>();
19
24
 
20
- function getAllowedOps(type: 'table' | 'view' | 'function'): APIOperation[] {
25
+ // Use the local alias or RLApiInterfaceActionParams['operation']
26
+ function getAllowedOps(type: 'table' | 'view' | 'function'): LocalAPIOperation[] {
21
27
  if (type === 'table') return ['GET', 'POST', 'PUT', 'DELETE'];
22
28
  if (type === 'view') return ['GET'];
23
- if (type === 'function') return ['POST']; // Typical for functions
29
+ if (type === 'function') return ['POST'];
24
30
  return [];
25
31
  }
26
32
 
27
- const operationDetails: Record<APIOperation, { label: string, class: string }> = {
33
+ const operationDetails: Record<LocalAPIOperation, { label: string, class: string }> = {
28
34
  GET: { label: 'GET', class: 'btn-info' },
29
35
  POST: { label: 'POST', class: 'btn-success' },
30
36
  PUT: { label: 'PUT', class: 'btn-warning' },
31
37
  DELETE: { label: 'DELETE', class: 'btn-error' },
32
38
  };
33
39
 
34
- function handleOperationClick(operation: APIOperation) {
40
+ function handleOperationClick(operation: LocalAPIOperation) {
41
+ // Construct the object that matches RLApiInterfaceActionParams
35
42
  onOpenModal({ operation });
36
43
  }
37
-
38
44
  </script>
39
45
 
40
46
  <div class="flex flex-wrap gap-2 my-2">
41
47
  {#each getAllowedOps(resourceType) as operation}
42
48
  {@const detail = operationDetails[operation]}
43
- {#if detail} <!-- Added a check in case an operation is not in details -->
49
+ {#if detail}
44
50
  <button
45
51
  class="btn btn-sm {detail.class}"
46
52
  onclick={() => handleOperationClick(operation)}
@@ -1,13 +1,11 @@
1
- import type { ColumnMetadata } from '@yrrrrrf/prism-ts';
2
- type APIOperation = 'GET' | 'POST' | 'PUT' | 'DELETE';
1
+ import type { ColumnMetadata as PrismColumnMetadata } from '@yrrrrrf/prism-ts';
2
+ import type { RLApiInterfaceActionParams } from '../stores/explorer.svelte.ts';
3
3
  type $$ComponentProps = {
4
4
  schemaName: string;
5
5
  resourceName: string;
6
6
  resourceType: 'table' | 'view' | 'function';
7
- columns: ColumnMetadata[];
8
- onOpenModal: (params: {
9
- operation: APIOperation;
10
- }) => void;
7
+ columns: PrismColumnMetadata[];
8
+ onOpenModal: (params: RLApiInterfaceActionParams) => void;
11
9
  };
12
10
  declare const RlApiInterface: import("svelte").Component<$$ComponentProps, {}, "">;
13
11
  type RlApiInterface = ReturnType<typeof RlApiInterface>;
@@ -0,0 +1,107 @@
1
+ <!-- src/lib/components/common/RLPropertyTable.svelte (example structure) -->
2
+ <script lang="ts">
3
+ import type { RLEnumMetadata, RLColumnReference } from '../stores/explorer.svelte';
4
+
5
+ export interface RLPropertyItem {
6
+ name: string;
7
+ type?: string;
8
+ nullable?: boolean;
9
+ isPrimaryKey?: boolean;
10
+ references?: RLColumnReference;
11
+ isEnum?: boolean;
12
+ mode?: string; // For function params
13
+ hasDefault?: boolean;
14
+ defaultValue?: string | null;
15
+ // Any other properties needed to render details
16
+ _rawItem?: any; // Optional: pass the original item if needed by slot
17
+ }
18
+
19
+ let {
20
+ items,
21
+ title = '',
22
+ nameHeader = "Name",
23
+ detailHeader = "Details",
24
+ enumsInSchema, // Pass this if needed for enum badge clicks from here
25
+ onFkClick,
26
+ onEnumClick,
27
+ } = $props<{
28
+ items: RLPropertyItem[];
29
+ title?: string;
30
+ nameHeader?: string;
31
+ detailHeader?: string;
32
+ enumsInSchema?: Record<string, RLEnumMetadata>; // For resolving enum names if items only have partial enum info
33
+ onFkClick?: (ref: RLColumnReference) => void;
34
+ onEnumClick?: (enumData: RLEnumMetadata) => void;
35
+ }>();
36
+ </script>
37
+
38
+ <div class="card bg-base-100 shadow-sm overflow-hidden my-2">
39
+ {#if title}
40
+ <div class="card-title p-3 text-sm font-semibold bg-base-200/50">{title}</div>
41
+ {/if}
42
+ <div class="card-body p-0">
43
+ {#if items && items.length > 0}
44
+ <div class="overflow-x-auto">
45
+ <table class="table table-sm w-full">
46
+ <thead>
47
+ <tr>
48
+ <th class="w-2/5 pl-4">{nameHeader}</th>
49
+ {#if detailHeader} <th class="w-3/5 pr-4">{detailHeader}</th> {/if}
50
+ </tr>
51
+ </thead>
52
+ <tbody>
53
+ {#each items as item (item.name)}
54
+ <tr class="hover">
55
+ <td class="align-top py-2 pl-4">
56
+ <div class="flex items-baseline">
57
+ <span class="font-medium">{item.name}</span>
58
+ {#if item.nullable === false && item.type && !item.type.toLowerCase().includes('bool')} <!-- Nullability for non-booleans -->
59
+ <span class="text-error ml-1 select-none" title="Required field">*</span>
60
+ {/if}
61
+ </div>
62
+ {#if item.type && detailHeader} <!-- Only show type if details are shown and type exists -->
63
+ <div class="font-mono text-xs text-base-content/60 italic mt-0.5">{item.type}</div>
64
+ {/if}
65
+ </td>
66
+ {#if detailHeader}
67
+ <td class="align-top py-2 pr-4 space-x-1.5">
68
+ {#if $$slots.detail}
69
+ <slot name="detail" itemData={item}></slot>
70
+ {:else}
71
+ <!-- Default detail rendering -->
72
+ {#if item.isPrimaryKey} <span class="badge badge-accent badge-xs font-semibold">PK</span> {/if}
73
+ {#if item.references}
74
+ <span class="badge badge-secondary badge-xs">FK</span>
75
+ <button class="link link-hover text-xs font-mono !text-info normal-case"
76
+ onclick={() => onFkClick && onFkClick(item.references!)}
77
+ title="Navigate to {item.references.schema}.{item.references.table}.{item.references.column}">
78
+ {item.references.schema}.{item.references.table}.{item.references.column}
79
+ </button>
80
+ {/if}
81
+ {#if item.isEnum && enumsInSchema && enumsInSchema[item.name + '_enum'] /* Crude example of finding enum */}
82
+ {@const enumMeta = enumsInSchema[item.name + '_enum']}
83
+ <button class="badge badge-warning badge-xs hover:shadow-md transition-shadow normal-case"
84
+ onclick={() => onEnumClick && onEnumClick(enumMeta)}
85
+ title="Enum: {enumMeta.name}">
86
+ <span class="mr-1 opacity-70">Enum:</span>{enumMeta.name}
87
+ </button>
88
+ {:else if item.isEnum}
89
+ <span class="badge badge-ghost badge-xs">Enum</span>
90
+ {/if}
91
+ {#if item.mode} <span class="badge badge-info badge-xs">{item.mode}</span> {/if}
92
+ {#if item.hasDefault} <span class="badge badge-outline badge-xs" title="Default: {item.defaultValue}">Has Default</span> {/if}
93
+ {/if}
94
+ </td>
95
+ {/if}
96
+ </tr>
97
+ {/each}
98
+ </tbody>
99
+ </table>
100
+ </div>
101
+ {:else}
102
+ <div class="p-4 text-center text-neutral-content/70">
103
+ No items to display.
104
+ </div>
105
+ {/if}
106
+ </div>
107
+ </div>
@@ -0,0 +1,44 @@
1
+ import type { RLEnumMetadata, RLColumnReference } from '../stores/explorer.svelte';
2
+ export interface RLPropertyItem {
3
+ name: string;
4
+ type?: string;
5
+ nullable?: boolean;
6
+ isPrimaryKey?: boolean;
7
+ references?: RLColumnReference;
8
+ isEnum?: boolean;
9
+ mode?: string;
10
+ hasDefault?: boolean;
11
+ defaultValue?: string | null;
12
+ _rawItem?: any;
13
+ }
14
+ type $$ComponentProps = {
15
+ items: RLPropertyItem[];
16
+ title?: string;
17
+ nameHeader?: string;
18
+ detailHeader?: string;
19
+ enumsInSchema?: Record<string, RLEnumMetadata>;
20
+ onFkClick?: (ref: RLColumnReference) => void;
21
+ onEnumClick?: (enumData: RLEnumMetadata) => void;
22
+ };
23
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
24
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
25
+ $$bindings?: Bindings;
26
+ } & Exports;
27
+ (internal: unknown, props: Props & {
28
+ $$events?: Events;
29
+ $$slots?: Slots;
30
+ }): Exports & {
31
+ $set?: any;
32
+ $on?: any;
33
+ };
34
+ z_$$bindings?: Bindings;
35
+ }
36
+ declare const RlPripertyTable: $$__sveltets_2_IsomorphicComponent<$$ComponentProps, {
37
+ [evt: string]: CustomEvent<any>;
38
+ }, {
39
+ detail: {
40
+ itemData: unknown;
41
+ };
42
+ }, {}, "">;
43
+ type RlPripertyTable = InstanceType<typeof RlPripertyTable>;
44
+ export default RlPripertyTable;
@@ -0,0 +1,61 @@
1
+ <!-- src/lib/components/dataview/RLDetailRow.svelte -->
2
+ <script lang="ts">
3
+ // No specific types needed from explorer.ts for these direct props.
4
+ // This component is highly generic.
5
+
6
+ type DetailAction = {
7
+ text: string;
8
+ class?: string;
9
+ onClick?: (event: MouseEvent) => void;
10
+ title?: string; // For tooltip on the badge/button
11
+ isLink?: boolean; // To render as a link-styled button
12
+ };
13
+
14
+ let {
15
+ name,
16
+ typeInfo = undefined,
17
+ details = [],
18
+ required = false,
19
+ description = undefined,
20
+ nameClass = 'font-medium',
21
+ typeInfoClass = 'font-mono text-xs text-base-content/60 italic mt-0.5',
22
+ containerClass = 'flex justify-between items-baseline py-1.5 hover:bg-base-content/5 px-1 rounded group',
23
+ } = $props<{
24
+ name: string;
25
+ typeInfo?: string;
26
+ details?: DetailAction[];
27
+ required?: boolean;
28
+ description?: string;
29
+ nameClass?: string;
30
+ typeInfoClass?: string;
31
+ containerClass?: string;
32
+ }>();
33
+ </script>
34
+
35
+ <div class="{containerClass}" title={description}>
36
+ <div class="flex-grow overflow-hidden pr-2">
37
+ <span class="{nameClass}">{name}</span>
38
+ {#if required}
39
+ <span class="text-error ml-1 select-none" title="Required field">*</span>
40
+ {/if}
41
+ {#if typeInfo}
42
+ <div class="{typeInfoClass} truncate" title={typeInfo}>{typeInfo}</div>
43
+ {/if}
44
+ </div>
45
+ {#if details.length > 0}
46
+ <div class="flex-shrink-0 space-x-1.5 flex items-center">
47
+ {#each details as detailItem}
48
+ <button
49
+ class="badge badge-sm whitespace-nowrap {detailItem.class || 'badge-ghost'}
50
+ {detailItem.isLink ? 'link link-hover !text-info normal-case font-mono' : ''}
51
+ disabled:opacity-50"
52
+ onclick={detailItem.onClick}
53
+ title={detailItem.title || detailItem.text}
54
+ disabled={!detailItem.onClick && !detailItem.isLink}
55
+ >
56
+ {@html detailItem.text} <!-- Use @html if text might contain simple entities like โ†’ -->
57
+ </button>
58
+ {/each}
59
+ </div>
60
+ {/if}
61
+ </div>
@@ -0,0 +1,20 @@
1
+ type DetailAction = {
2
+ text: string;
3
+ class?: string;
4
+ onClick?: (event: MouseEvent) => void;
5
+ title?: string;
6
+ isLink?: boolean;
7
+ };
8
+ type $$ComponentProps = {
9
+ name: string;
10
+ typeInfo?: string;
11
+ details?: DetailAction[];
12
+ required?: boolean;
13
+ description?: string;
14
+ nameClass?: string;
15
+ typeInfoClass?: string;
16
+ containerClass?: string;
17
+ };
18
+ declare const RlDetailRow: import("svelte").Component<$$ComponentProps, {}, "">;
19
+ type RlDetailRow = ReturnType<typeof RlDetailRow>;
20
+ export default RlDetailRow;
@@ -0,0 +1,53 @@
1
+ <!-- src/lib/components/dataview/RLMetadataList.svelte -->
2
+ <script lang="ts">
3
+ import RLDetailRow from './RLDetailRow.svelte';
4
+
5
+ type DetailActionForList = { // Prop structure for items passed to RLDetailRow
6
+ text: string;
7
+ class?: string;
8
+ onClick?: (event: MouseEvent) => void;
9
+ title?: string;
10
+ isLink?: boolean;
11
+ };
12
+
13
+ export interface RLMetadataListItem {
14
+ name: string;
15
+ typeInfo?: string;
16
+ details?: DetailActionForList[];
17
+ required?: boolean;
18
+ description?: string;
19
+ }
20
+
21
+ let {
22
+ title = undefined,
23
+ items = [],
24
+ listClass = 'divide-y divide-base-300/50',
25
+ emptyText = 'None.',
26
+ } = $props<{
27
+ title?: string;
28
+ items: RLMetadataListItem[];
29
+ listClass?: string;
30
+ emptyText?: string;
31
+ }>();
32
+ </script>
33
+
34
+ <div>
35
+ {#if title}
36
+ <h4 class="font-semibold text-sm mb-1 mt-2 opacity-80">{title}</h4>
37
+ {/if}
38
+ {#if items.length > 0}
39
+ <div class="{listClass} border-t border-b border-base-300/30 -mx-1">
40
+ {#each items as item (item.name) }
41
+ <RLDetailRow
42
+ name={item.name}
43
+ typeInfo={item.typeInfo}
44
+ details={item.details}
45
+ required={item.required}
46
+ description={item.description}
47
+ />
48
+ {/each}
49
+ </div>
50
+ {:else}
51
+ <p class="text-xs text-base-content/50 italic py-1.5 px-1">{emptyText}</p>
52
+ {/if}
53
+ </div>
@@ -0,0 +1,23 @@
1
+ type DetailActionForList = {
2
+ text: string;
3
+ class?: string;
4
+ onClick?: (event: MouseEvent) => void;
5
+ title?: string;
6
+ isLink?: boolean;
7
+ };
8
+ export interface RLMetadataListItem {
9
+ name: string;
10
+ typeInfo?: string;
11
+ details?: DetailActionForList[];
12
+ required?: boolean;
13
+ description?: string;
14
+ }
15
+ type $$ComponentProps = {
16
+ title?: string;
17
+ items: RLMetadataListItem[];
18
+ listClass?: string;
19
+ emptyText?: string;
20
+ };
21
+ declare const RlMetadataList: import("svelte").Component<$$ComponentProps, {}, "">;
22
+ type RlMetadataList = ReturnType<typeof RlMetadataList>;
23
+ export default RlMetadataList;
@@ -1,6 +1,7 @@
1
1
  <!-- src/lib/components/dataview/RLMetadataTable.svelte -->
2
2
  <script lang="ts">
3
3
  import type { ColumnMetadata, ColumnReference, EnumMetadata } from '@yrrrrrf/prism-ts';
4
+ import { formatReferenceText } from '../../tools/form-helpers.js';
4
5
 
5
6
  let {
6
7
  title,
@@ -18,10 +19,6 @@
18
19
  onEnumClick?: (enumData: { name: string; values: string[] }) => void; // Make optional
19
20
  }>();
20
21
 
21
- function formatReferenceText(ref: ColumnReference | undefined): string {
22
- if (!ref) return '';
23
- return `${ref.schema}.${ref.table}.${ref.column}`;
24
- }
25
22
 
26
23
  function handleFkButtonClick(ref: ColumnReference | undefined) {
27
24
  if (ref && onFkClick) {
@@ -0,0 +1,34 @@
1
+ <!-- src/lib/components/explorer/RLEnumDisplay.svelte -->
2
+ <script lang="ts">
3
+ import type { RLEnumMetadata } from '../stores/explorer.svelte';
4
+ import RLMetadataList from '../dataview/RLMetadataList.svelte'; // Adjust path as needed
5
+
6
+ let {
7
+ enumData,
8
+ // Optional: if RLEnumDisplay should have its own modal button.
9
+ // Otherwise, RLSchemaExplorer can handle showing the modal if needed via context.
10
+ // For simplicity, let's assume any modal action is handled by the parent (RLSchemaExplorer).
11
+ } = $props<{
12
+ enumData: RLEnumMetadata;
13
+ }>();
14
+
15
+ let enumValueItems = $derived(
16
+ enumData.values.map((value: string) => ({
17
+ name: value,
18
+ }))
19
+ );
20
+ </script>
21
+
22
+ <div class="py-2">
23
+ <RLMetadataList items={enumValueItems} title="Values" emptyText="No values defined for this enum." />
24
+ <!--
25
+ If RLSchemaExplorer needs a way to open its existing enum modal from here,
26
+ you could add a button and an on:click event that bubbles up or calls a prop function.
27
+ Example:
28
+ <div class="mt-2">
29
+ <button class="btn btn-xs btn-outline" on:click>
30
+ Show in Modal (if needed)
31
+ </button>
32
+ </div>
33
+ -->
34
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { RLEnumMetadata } from '../stores/explorer.svelte';
2
+ type $$ComponentProps = {
3
+ enumData: RLEnumMetadata;
4
+ };
5
+ declare const RlEnumDisplay: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type RlEnumDisplay = ReturnType<typeof RlEnumDisplay>;
7
+ export default RlEnumDisplay;
@@ -0,0 +1,64 @@
1
+ <!-- src/lib/components/explorer/RLFunctionDisplay.svelte -->
2
+ <script lang="ts">
3
+ import type { RLApiInterfaceActionParams, RLFunctionMetadata, RLFunctionParameter } from '../stores/explorer.svelte';
4
+
5
+ import RLDetailRow from '../dataview/RLDetailRow.svelte';
6
+ import RLMetadataList from '../dataview/RLMetadataList.svelte';
7
+ import type { RLMetadataListItem } from '../dataview/RLMetadataList.svelte';
8
+ import RLApiInterface from '../api/RLApiInterface.svelte'; // For execution
9
+
10
+ let {
11
+ func,
12
+ onOpenApiModal, // Callback to RLSchemaExplorer
13
+ } = $props<{
14
+ func: RLFunctionMetadata;
15
+ onOpenApiModal: (params: RLApiInterfaceActionParams & { schemaName: string, resourceName: string, resourceType: 'function', options: any }) => void;
16
+ }>();
17
+
18
+ let parameterItems = $derived(
19
+ func.parameters.map((param: RLFunctionParameter): RLMetadataListItem => ({
20
+ name: param.name,
21
+ typeInfo: param.type + (param.defaultValue ? ` (default: ${param.defaultValue})` : ''),
22
+ required: !param.hasDefault && param.mode === 'IN', // Only IN params can be "required" in a form sense
23
+ details: [{ text: param.mode, class: `badge-${param.mode === 'IN' ? 'info' : param.mode === 'OUT' ? 'success' : 'warning'}` }],
24
+ }))
25
+ );
26
+ </script>
27
+
28
+ <div class="space-y-3 py-2">
29
+ {#if func.description}
30
+ <RLDetailRow name="Description" typeInfo={func.description} nameClass="font-semibold opacity-80" typeInfoClass="italic text-sm" />
31
+ {/if}
32
+
33
+ <RLDetailRow name="Kind" typeInfo={func.kind} nameClass="font-semibold opacity-80" />
34
+ <RLDetailRow name="Return Type" typeInfo={func.returnType || 'void'} nameClass="font-semibold opacity-80" />
35
+ <RLDetailRow name="Is Strict" typeInfo={func.isStrict ? 'Yes' : 'No'} nameClass="font-semibold opacity-80" />
36
+
37
+ {#if func.kind === 'TRIGGER' && func.triggerData}
38
+ <RLMetadataList title="Trigger Details" items={[
39
+ { name: 'Timing', typeInfo: func.triggerData.timing },
40
+ { name: 'Events', typeInfo: func.triggerData.events.join(', ') },
41
+ { name: 'Target', typeInfo: `${func.triggerData.targetTableSchema}.${func.triggerData.targetTableName}` },
42
+ ]} />
43
+ {/if}
44
+
45
+ <RLMetadataList items={parameterItems} title="Parameters" emptyText="No parameters." />
46
+
47
+ {#if (func.kind === 'FUNCTION' || func.kind === 'PROCEDURE') && onOpenApiModal}
48
+ <div class="mt-4 pt-3 border-t border-base-300/30">
49
+ <RLApiInterface
50
+ schemaName={func.schema}
51
+ resourceName={func.name}
52
+ resourceType={'function'}
53
+ columns={[]}
54
+ onOpenModal={(opParams) => onOpenApiModal({
55
+ ...opParams,
56
+ schemaName: func.schema,
57
+ resourceName: func.name,
58
+ resourceType: 'function',
59
+ options: { functionParams: func.parameters } // Passing RLFunctionParameter[]
60
+ })}
61
+ />
62
+ </div>
63
+ {/if}
64
+ </div>
@@ -0,0 +1,13 @@
1
+ import type { RLApiInterfaceActionParams, RLFunctionMetadata } from '../stores/explorer.svelte';
2
+ type $$ComponentProps = {
3
+ func: RLFunctionMetadata;
4
+ onOpenApiModal: (params: RLApiInterfaceActionParams & {
5
+ schemaName: string;
6
+ resourceName: string;
7
+ resourceType: 'function';
8
+ options: any;
9
+ }) => void;
10
+ };
11
+ declare const RlFunctionDisplay: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type RlFunctionDisplay = ReturnType<typeof RlFunctionDisplay>;
13
+ export default RlFunctionDisplay;