Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
770cf01
Add initial 1.0.0 datatypes
MV-GH May 3, 2025
86c2b42
Add Initial new uni types changes
MV-GH May 25, 2025
b353beb
Make all impl specific typealias internal
MV-GH May 25, 2025
cf1ef56
Fix some TODOs
MV-GH May 25, 2025
db6fff0
Fix dynamic types with Kotlinx.serialization polymorphic
MV-GH May 25, 2025
0dd88ab
Fix GetModLogs transformation
MV-GH May 25, 2025
b492d5e
Wip comment changes v2
MV-GH Jun 30, 2025
76b2297
Merge branch 'master' into lemmy-1.0.0
MV-GH Jul 1, 2025
a3b7c21
WIP: Sync uni types with 1.0.0 types
MV-GH Sep 15, 2025
6a1e9cf
Some more fields
MV-GH Sep 15, 2025
ecf7eb1
Fix LocalUserVoteDisplayMode
MV-GH Sep 15, 2025
c7dda7a
Remove SiteAggregates
MV-GH Sep 16, 2025
7db3d6e
Fix taglines
MV-GH Sep 16, 2025
0ec55f6
Fix Search mappings
MV-GH Sep 17, 2025
ef8dc71
Fix ListReports
MV-GH Sep 23, 2025
c8d2d31
Count fixes
MV-GH Sep 23, 2025
95f4743
Remove ModlogListParams
MV-GH Sep 23, 2025
2593c98
Fix inbox endpoints
MV-GH Sep 29, 2025
d3e3f85
Remove wrong deps
MV-GH Sep 30, 2025
81a67d0
Update non null reason
MV-GH Sep 30, 2025
1c350ac
Update non null reason
MV-GH Sep 30, 2025
70e3d50
Fix backup
MV-GH Sep 30, 2025
df7437c
Fix LinkMetadata.kt
MV-GH Oct 1, 2025
98b107f
Fix Comment.kt
MV-GH Oct 1, 2025
8863bf8
Fix PersonView.kt LocalUserView.kt
MV-GH Oct 2, 2025
3b3c02d
Fix Site dtos
MV-GH Oct 6, 2025
4cc16f2
Fix Post
MV-GH Oct 6, 2025
a3d2cb5
Fix PostView
MV-GH Oct 6, 2025
40a8f38
Fix CommentView
MV-GH Oct 6, 2025
b0cb414
Fix ModLog renaming
MV-GH Oct 7, 2025
a8ee330
Fix todos
MV-GH Oct 7, 2025
b4dbba7
Fix more todos
MV-GH Oct 8, 2025
84eeaf9
Fix listCustomEmojis
MV-GH Oct 9, 2025
4e54be4
Fix myUserInfo
MV-GH Oct 9, 2025
23a2424
Fix CommentResponse.kt
MV-GH Oct 10, 2025
9120dec
Apply MarkManyPostsAsRead changes
MV-GH Feb 22, 2026
4bc06f3
Wip progress 1.0.0 types mapping
MV-GH Mar 3, 2026
2560e01
Refactor enums infra
MV-GH Mar 3, 2026
1633061
Fix more changes
MV-GH Mar 3, 2026
0d9793e
Fix more changes
MV-GH Mar 3, 2026
e261588
Fix enums
MV-GH Mar 7, 2026
9e0335c
Add remaining enums
MV-GH Mar 7, 2026
30697fe
Fix imports
MV-GH Mar 7, 2026
0379e94
Fix listPostLikes and listCommentLikes
MV-GH Mar 8, 2026
b8947be
Small tweaks
MV-GH Mar 8, 2026
51e6dba
SearchCombinedView changes
MV-GH Mar 8, 2026
422e16d
Remove ResolveObjectResponse
MV-GH Mar 8, 2026
8e563d2
Fix NotificationData
MV-GH Mar 8, 2026
1f8b5f6
Remove remnants
MV-GH Mar 8, 2026
b7958c3
Fix ReportCombinedView
MV-GH Mar 8, 2026
1ef61ad
Fix PostOrCommentOrPrivateMessage interface
MV-GH Mar 8, 2026
f6a72a8
Fix Community
MV-GH Mar 9, 2026
854572a
Add PostCommentCombinedView
MV-GH Mar 9, 2026
0208212
Add ListPersonContent
MV-GH Mar 9, 2026
5145c5b
Fix GetPersonDetails endpoint
MV-GH Mar 9, 2026
c20d5a9
Add init version of LemmyApiController LemmyApiRouter
MV-GH May 23, 2026
4c9677c
v1 endpoint tweaks
MV-GH May 23, 2026
ee53202
v1 endpoint tweaks
MV-GH May 23, 2026
1585033
Pictrs changes
MV-GH May 23, 2026
f86201d
Implement image endpoints
MV-GH May 23, 2026
17e7814
Fix datatypes
MV-GH May 23, 2026
0101cbf
Add non supported v1 endpoints
MV-GH May 23, 2026
a5721f0
Tweak
MV-GH May 23, 2026
cd71e80
Fix ListLogins
MV-GH May 23, 2026
b13c755
Fix hidePost
MV-GH May 23, 2026
c1c0743
Fix transferCommunity
MV-GH May 23, 2026
d0ce128
Remove todo
MV-GH May 23, 2026
6ea6014
Apply linter + Mapper
MV-GH May 24, 2026
1b91c4f
Add uniWrapper for V1
MV-GH May 24, 2026
3fb78ad
Bump deps
MV-GH May 24, 2026
8348f7c
Fix enums nont snake_case
MV-GH May 24, 2026
4ba8f69
Bump AGP + remove remnants
MV-GH May 24, 2026
7cb1879
Update types
MV-GH May 24, 2026
739c97f
Fix types
MV-GH May 24, 2026
ee7d41b
Update types
MV-GH May 24, 2026
badc578
Update the genTypes script
MV-GH May 24, 2026
f698e9c
Add ListPersons endpoint
MV-GH May 24, 2026
fc726a0
Tweak for warning
MV-GH May 24, 2026
c07e1ee
Update genTypes
MV-GH May 24, 2026
4f3c381
Update site types
MV-GH May 24, 2026
5f2da70
Update GenTypes.kt
MV-GH May 24, 2026
3c1c212
Update Search and SearchResponse types
MV-GH May 24, 2026
54cac47
Fix lint
MV-GH May 24, 2026
dda22b2
Implement support for icon/banner/avatar removal endpoints for preV1
MV-GH May 24, 2026
41632ed
Remove update banner/icon/avatar from public API
MV-GH May 24, 2026
0afb031
Rename apiV18 to api
MV-GH May 24, 2026
91321bd
Remove InstanceWithFederationState remnants
MV-GH May 24, 2026
7b5c8f0
Fix couple types
MV-GH May 24, 2026
5624ca3
Update Site types
MV-GH May 24, 2026
2c73157
Update todos
MV-GH May 24, 2026
30c0b62
Update some descriptions
MV-GH May 24, 2026
7e3cb78
Documentation changes
MV-GH May 24, 2026
428d2dc
Bump version
MV-GH May 24, 2026
94481f2
Bump kotlinter + Android compile SDK
MV-GH May 24, 2026
3711b21
Bump publish plugin
MV-GH May 24, 2026
ece7de1
Change deployment flow to fix OOM for gradle
MV-GH May 24, 2026
0289a7a
Fix unit
MV-GH May 24, 2026
48ee68e
Fix remnant
MV-GH May 24, 2026
24f4ff4
Increase timeout to download wrapper
MV-GH May 24, 2026
c1849f0
Increase gradle mem
MV-GH May 24, 2026
c4ccfba
Try fix duplicate deployment
MV-GH May 25, 2026
677b6e6
Bump semver
MV-GH May 25, 2026
5333a9c
Try new deployment
MV-GH May 25, 2026
d82cbaf
Try new deployment
MV-GH May 25, 2026
f061e50
Try deployment on one machine
MV-GH May 25, 2026
eaa7880
Fix default_comment_sort_type
MV-GH Jun 21, 2026
f549211
Update types to 1.0.0-beta.1
MV-GH Jul 8, 2026
694a347
Move uploadAndApplyImage to super
MV-GH Jul 8, 2026
2cfd69f
Remove icon & banner from CreateCommunity.kt
MV-GH Jul 8, 2026
348affd
Add new Invitation endpoints
MV-GH Jul 8, 2026
85a0dba
Deploy new version
MV-GH Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 0 additions & 2 deletions .github/gradle.properties

This file was deleted.

26 changes: 10 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,15 @@ jobs:
os: [ macos-latest, ubuntu-latest, windows-latest ]

steps:
- uses: actions/checkout@v4
- uses: SimonMarquis/ci-gradle-properties-action@v1
with:
path: .github/gradle.properties
- uses: actions/setup-java@v4
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v5
- name: Cache Konan dependencies
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.konan
key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle.kts') }}
Expand All @@ -40,10 +37,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- uses: actions/setup-java@v4
uses: gradle/actions/setup-gradle@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
Expand All @@ -52,13 +49,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: SimonMarquis/ci-gradle-properties-action@v1
with:
path: .github/gradle.properties
- uses: actions/checkout@v6
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- uses: actions/setup-java@v4
uses: gradle/actions/setup-gradle@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
Expand Down
22 changes: 11 additions & 11 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ name: Deployment
on:
push:
tags: [ '[0-9]+.[0-9]+.[0-9]+*' ]
workflow_dispatch:

jobs:
publish:
if: github.repository == 'mv-gh/lemmybackwardscompatibleapi' && startsWith(github.ref, 'refs/tags')
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macos-latest, ubuntu-latest, windows-latest ]
if: >
github.repository == 'mv-gh/lemmybackwardscompatibleapi' &&
(
startsWith(github.ref, 'refs/tags/') ||
(github.event_name == 'workflow_dispatch' && github.actor == 'mv-gh')
)
runs-on: macos-latest
environment: publish
env:
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}
Expand All @@ -19,13 +22,10 @@ jobs:
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyId }}
steps:
- uses: actions/checkout@v4
- uses: SimonMarquis/ci-gradle-properties-action@v1
with:
path: .github/gradle.properties
- uses: actions/checkout@v6
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- uses: actions/setup-java@v4
uses: gradle/actions/setup-gradle@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
Expand Down
32 changes: 31 additions & 1 deletion ACTIVE_CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@
This document lists the changes that you will need to actively handle, through feature flags.


## V1

### Sort types split + `time_range_seconds`

The many `Top*` `SortType` variants (`TopDay`, `TopWeek`, `TopMonth`, `TopYear`, `TopAll`, `TopHour`, `TopSixHour`, `TopTwelveHour`, `TopThreeMonths`, `TopSixMonths`, `TopNineMonths`) have been collapsed into a single `Top` value in v1. Time range is now expressed via `time_range_seconds: Long?` on the query (`GetPosts`, `GetComments`, `ListCommunities`, `ListMultiCommunities`, `Search`).

- On v1, set `sort = SortType.Top` and pass `time_range_seconds` (e.g. `86400` for top day).
- On pre-v1, the old `Top*` variants are still used; `time_range_seconds` is ignored. The wrapper translates automatically.

### Image upload / delete compatibility

- Consumers should use `LemmyApiBaseController.uploadImage()` and `LemmyApiBaseController.deleteMedia()`.
- Pre-1.0 Lemmy instances are now wired internally to legacy pictrs endpoints; callers should not use pictrs APIs directly anymore.
- `UploadImageResponse` now includes `delete_filename`.
- Always pass `uploadImage(...).delete_filename` into `deleteMedia(DeleteImageParams(...))`.
- On Lemmy `1.x`, `delete_filename == filename`.
- On pre-`1.0`, `delete_filename` contains the full legacy pictrs delete path, like `/pictrs/image/delete/{delete_token}/{file}`.

### Avatar/Icon/Banner

Should now use the dedicated avatar/icon/banner upload/delete endpoints.

### Pagination: `page` replaced by `page_cursor`

`page: Long?` has been removed from all list/query types in v1 (`GetPosts`, `GetComments`, `GetModlog`, `Search`, `ListCommunities`, `ListReports`, `ListNotifications`, `ListMedia`, `ListPersonContent`, `ListPostLikes`, `ListCommentLikes`, `ListRegistrationApplications`).

- On v1, use `page_cursor` for cursor-based pagination.
- To support pre-v1 instances, populate **both** `page` (for older versions, handled internally) and `page_cursor` (for v1). The wrapper will pass the appropriate one.



## 0.19.11

- Added `last_donation_notification` field to LocalUser
Expand All @@ -29,4 +60,3 @@ But each has different behaviour. The old behaviour is to hide all voting types
- Log out support (invalidates the current JWT)
- Instance block support
- 2FA rework, one must now provide a valid 2FA code to enable 2FA. Added routes to support this.

65 changes: 65 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Contributing to this project


## Architecture

```
LemmyApi (factory object)
└─ getLemmyApi(instance, version) → LemmyApiBaseController
└─ version-specific LemmyApiUniWrapper (implements LemmyApiBaseController)
├─ LemmyApiController (raw Ktor HTTP calls, version-specific datatypes)
├─ Transformer (maps version-specific ↔ unified datatypes)
└─ MapperGenerator (interface) (declares all toUni/fromUni signatures)
```

### Per-version module structure

Each `vX/xN/xM/` folder contains exactly these files:

| File | Purpose |
|---|---|
| `datatypes/` | Auto-generated version-specific Kotlin datatypes. **Do not edit by hand.** |
| `MapperGenerator.kt` | Interface declaring all `toUni` / `fromUni` signatures, used to drive Konvert code generation. Annotations are commented out in committed code; uncomment + build to regenerate. |
| `Transformer.kt` | Implements `MapperGenerator`. Contains all field-level mapping logic. Generated initially by Konvert, then hand-maintained for non-trivial differences. |
| `LemmyApiUniWrapper.kt` | Implements `LemmyApiBaseController`. Delegates HTTP calls to `LemmyApiController` and transforms results. Unsupported endpoints call `notSupported()`. |
| `LemmyApiController.kt` | Raw Ktor HTTP calls returning version-specific datatypes. |
| `LemmyApiRouter.kt` | Route path definitions for this version. |

### Unified datatypes (1.0.0 baseline)

The `it.vercruysse.lemmyapi.datatypes` package represents the **1.0.0 Lemmy API** and is the single source of truth for all API consumers. Older version wrappers transform their version-specific types into these unified types. See `ACTIVE_CHANGES.md` for the key API differences consumers need to handle.


## Backwards Compatibility Strategy

- **API route added**: add a function to `FeatureFlags` that returns whether this feature is supported. Older versions implement this route by throwing `notSupported()`.
- **API route removed**: newer versions implement the old route by throwing `notSupported()`. Add to the `oldRoutes` interface if needed.
- **Request/response changes**: transform using `Transformer`. The unified type (usually the latest datatype shape) is returned regardless of version. Example: [moving admin flag from person to local_user](https://github.com/LemmyNet/lemmy/pull/3403) — pre-0.19 APIs map their type to the latest shape.
- **Enum entries**: each entry tracks `minimumVersion`/`maximumVersion`. Use `getSupportedEntries<Type>()` to retrieve the valid entries for the connected instance (e.g. sort options).


## Compatibility Rules

When adding or updating an older-version implementation:

1. **Reference `v0.x18.x5`** — it is always kept up-to-date with the unified interface. Copy its `LemmyApiUniWrapper.kt` pattern.
2. `MapperGenerator.kt` return types must use **unified** types only.
3. `Transformer.kt` must not import deleted unified types.
4. `LemmyApiUniWrapper.kt` must implement **every** abstract method from `LemmyApiBaseController`. Missing features use `notSupported()`.
5. Import aliases are required in `Transformer.kt`:
- Unified types: `import it.vercruysse.lemmyapi.datatypes.Foo as LemmyapiDatatypesFoo`
- Local version types: `import it.vercruysse.lemmyapi.vX.xN.xM.datatypes.Foo as XMDatatypesFoo`
- Unused aliases cause compilation errors — remove them when the corresponding method is deleted.


## AutoGenerated Code

To minimize the maintenance burden, many aspects have been automated via Kotlin scripts in the `GeneratorScripts` submodule:

- **`GenTypes`**: Downloads TS types from [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client) and generates `datatypes/` for a target version. Requires [dukat](https://github.com/Kotlin/dukat).
- **`GenRoutes`**: Generates route/controller templates from [lemmy_openapi_spec](https://github.com/MV-GH/lemmy_openapi_spec). Output goes to `temp/`.
- **`GenMapperRoutes`**: Generates `MapperGenerator.kt` by diffing two version datatypes. Uncomment the Konvert annotations and build to generate `Transformer.kt` base, then copy from the build output. Output goes to `temp/`.

See `STEPS_TO_SUPPORT_MORE_VERSION.md` for the full checklist when adding a new Lemmy version.

18 changes: 9 additions & 9 deletions GeneratorScripts/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
kotlin("jvm")
kotlin("plugin.serialization") version "2.1.10"
id("com.google.devtools.ksp").version("2.1.10-1.0.30")
kotlin("plugin.serialization") version "2.3.21"
id("com.google.devtools.ksp").version("2.3.8")
}

repositories {
Expand All @@ -11,19 +11,18 @@ repositories {
dependencies {
testImplementation("org.jetbrains.kotlin:kotlin-test")
implementation("com.charleskorn.kaml:kaml:0.55.0")
val ktorVersion = "3.1.2"
val konvertVersion = "3.2.1"
val ktorVersion = "3.5.0"
val konvertVersion = "4.5.0"
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0")

implementation("com.squareup.okio:okio:3.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.6.0")
implementation("io.mcarle:konvert:$konvertVersion")
implementation("com.squareup.okio:okio:3.17.0")
implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.9.0")
implementation("io.mcarle:konvert-api:$konvertVersion")
implementation(project(":app"))

Expand All @@ -37,3 +36,4 @@ tasks.test {
kotlin {
jvmToolchain(17)
}

Loading
Loading