logseq / logseq/plugins

[Feature Request] Extend Plugin API for full ontology import/export parity in DB graphs

Abierto
#32 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
HTML
Estrellas
26
Forks
8
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

### Problem Statement

The Plugin API for DB graphs does not support all fields that Logseq exports in its native EDN format. This prevents plugins from implementing complete ontology import/export functionality.

When users export ontology from a DB graph and attempt to re-import it via a plugin, some data is lost:

| Data Type | Fields in EDN Export | Fields Settable via API | Lost on Import |
|-----------|---------------------|------------------------|----------------|
| Properties | 14 | 10 | **4 fields (29%)** |
| Classes/Tags | 7 | 6 | **1 field (14%)** |

### What Works (Discovered Feb 2025)

Through extensive console testing, we discovered workarounds for several fields:

#### System Description Field

Using the **full namespaced key** with `upsertBlockProperty` sets the system description:

```typescript
// ❌ WRONG - creates a user property named "description"
await logseq.Editor.upsertBlockProperty(uuid, 'description', 'My description')

// ✅ CORRECT - sets the system logseq.property/description field
await logseq.Editor.upsertBlockProperty(uuid, ':logseq.property/description', 'My description')
```

The value is stored as an entity reference (Logseq creates a new entity containing the text).

#### Tabler Icons on Properties and Tags

`setBlockIcon()` **works for Tabler icons** on properties and tags:

```typescript
// ✅ Works - Tabler icon on property
const prop = await logseq.Editor.getProperty('my-property')
await logseq.Editor.setBlockIcon(prop.uuid, 'tabler-icon', 'star')

// ✅ Works - Tabler icon on tag
const tag = await logseq.Editor.getTag('MyTag')
await logseq.Editor.setBlockIcon(tag.uuid, 'tabler-icon', 'folder')
```

### What Doesn't Work

#### Emoji Icons - Lookup Table Inaccessible

`setBlockIcon()` **fails for all emoji formats**:

```typescript
await logseq.Editor.setBlockIcon(uuid, 'emoji', 'rocket') // ❌ "Can't find emoji for rocket"
await logseq.Editor.setBlockIcon(uuid, 'emoji', '🚀') // ❌ "Can't find emoji for 🚀"
await logseq.Editor.setBlockIcon(uuid, 'emoji', ':rocket:') // ❌ "Can't find emoji for :rocket:"
```

**Root cause:** Logseq's emoji lookup table is internal and not accessible to plugins. The EDN export shows emojis stored with numeric IDs (e.g., `{:type :emoji, :id "100"}`) but there's no way for plugins to discover or use these IDs.

#### Class/Tag Title - Ownership Restriction

Attempting to set `:logseq.class/title` fails:

```typescript
await logseq.Editor.upsertBlockProperty(tagUuid, ':logseq.class/title', 'My Display Title')
// ❌ Error: "Plugins can only upsert its own properties"
```

Unlike `:logseq.property/description` which works, the title field is blocked.

### Remaining Fields Not Settable via Plugin API

#### Properties

| Missing Field | Impact |
|---------------|--------|
| **icon (emoji only)** | Cannot set emoji icons (Tabler icons work) |
| **closedValues** | Cannot create enum/choice/select properties |
| **datetime type** | Must downgrade to `date` (loses time component) |
| **position** | Cannot control UI ordering |
| **default** | Cannot set default values |

#### Classes/Tags

| Missing Field | Impact |
|---------------|--------|
| **icon (emoji only)** | Cannot set emoji icons (Tabler icons work) |
| **title** | Cannot set display name (blocked by ownership restriction) |
| **position** | Cannot control UI ordering |

### Use Case

I'm building an ontology import plugin that allows users to:
1. Export ontology definitions from one DB graph
2. Share them via a marketplace/repository
3. Import them into another DB graph

Currently, imported ontologies lose emoji icons, enum configurations (closedValues), and display titles. Tabler icons and descriptions now import successfully.

### Proposed Solutions

#### 1. Expose emoji lookup or accept emoji characters directly

Either:
- **Option A:** Accept emoji characters directly in `setBlockIcon`: `setBlockIcon(uuid, 'emoji', '🚀')`
- **Option B:** Accept standard emoji names: `setBlockIcon(uuid, 'emoji', 'rocket')`
- **Option C:** Document the emoji ID format so plugins can use it

#### 2. Add `closedValues` support to `upsertProperty`

```typescript
upsertProperty(key: string, schema?: {
// Existing fields...

// Requested addition
closedValues?: Array<{
value: string;
icon?: { type: "emoji" | "tabler-icon"; id: string };
description?: string;
}>;
}): Promise
```

#### 3. Allow setting class/tag title

Either remove the ownership restriction for `:logseq.class/title` or add it to the `createTag` options:

```typescript
createTag(name: string, opts?: {
uuid?: string; // Existing
title?: string; // Requested
}): Promise
```

#### 4. Add `datetime` property type

Currently `datetime` must be downgraded to `date`, losing the time component.

### Priority Ranking

1. 🔴 **Critical:** Fix emoji icon setting (expose lookup or accept characters) - Icons are the primary visual identity of ontology elements; losing them during import significantly degrades the user experience
2. 🔴 **Critical:** Add `closedValues` support to `upsertProperty` - Required for enum/select properties
3. 🟡 **Medium:** Allow setting class/tag title
4. 🟡 **Medium:** Add `datetime` property type
5. 🟢 **Low:** Add `position` to schema APIs

### Environment

- Logseq version: 2.0.0 (DB graph mode)
- Platform: Windows
- Plugin API version: @logseq/libs latest

### What We Learned (Testing Details)

For reference, here's what we discovered through console testing:

| Feature | Method | Status |
|---------|--------|--------|
| System Description | `upsertBlockProperty(uuid, ':logseq.property/description', text)` | ✅ Works |
| Tabler Icons | `setBlockIcon(uuid, 'tabler-icon', 'iconName')` | ✅ Works |
| Emoji Icons | `setBlockIcon(uuid, 'emoji', ...)` | ❌ All formats fail |
| Class Title | `upsertBlockProperty(uuid, ':logseq.class/title', text)` | ❌ Ownership blocked |
| Icon via upsertBlockProperty | `upsertBlockProperty(uuid, ':logseq.property/icon', {...})` | ❌ Renders "Invalid icon" |

**Key insight:** `setBlockIcon` stores icons as `{type: 'tablerIcon', id: 'name'}` (camelCase), but setting this format directly via `upsertBlockProperty` still renders as "Invalid icon" - there's internal processing in `setBlockIcon` that can't be replicated.

### Additional Context

Full field-by-field reconciliation available here: [API Field Reconciliation Document](https://github.com/C0ntr0lledCha0s/logseq-ontology-sync-plugin/blob/main/docs/api-field-reconciliation.md)

This enhancement would enable a richer ecosystem of ontology sharing and template plugins for DB graphs.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con los puntos de entrada de @logseq/libs mencionados en el issue: setBlockIcon, upsertProperty, upsertBlockProperty y createTag. Lee docs/api-field-reconciliation.md y reproduce las carencias documentadas de importación/exportación del grafo de DB; el trabajo estará terminado cuando los campos de ontología solicitados, incluidos los iconos emoji, closedValues, títulos, datetime y position, puedan hacer un round-trip a través de la API del plugin.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
api
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.