Skip to content

Commit b0b498c

Browse files
Added README as entry for dev documentation and updated all documentation pages.
1 parent 7c8d05f commit b0b498c

5 files changed

Lines changed: 528 additions & 84 deletions

File tree

documentation/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Developer Documentation
2+
3+
Welcome to the elek.io Client developer documentation. This guide will help you understand the codebase architecture and development patterns.
4+
5+
> [!NOTE]
6+
> If your main interest is using Projects content inside your own applications, you can skip to the [Consuming Content Locally](./consuming-content-locally.md) section.
7+
8+
## Prerequisites
9+
10+
- Familiarity with TypeScript and React
11+
- Basic understanding of Electron architecture
12+
- Knowledge of React Hook Form and TanStack Query (helpful but not required)
13+
- Understanding of Git and version control concepts
14+
15+
## Getting Started
16+
17+
**Start with [Overview](./overview.md)** to understand the application architecture, security model, and how the different processes communicate.
18+
19+
Then proceed to the specific topics based on your interests or contribution goals:
20+
21+
- **[Loading and Updating Data](./renderer/loading-and-updating-data.md)** - TanStack Query patterns for data fetching and mutations
22+
- **[Dynamic Form Generation](./renderer/dynamic-form-field-generation.md)** - How user-defined forms work with field definitions
23+
24+
## Contributing
25+
26+
When updating these docs:
27+
28+
- Keep code examples up-to-date with actual implementation
29+
- Include file references with line numbers where relevant
30+
- Add practical examples for complex concepts
31+
- Update the "Last Updated" date at the bottom of each document
32+
33+
## Additional Resources
34+
35+
- [Electron Documentation](https://www.electronjs.org/docs/latest)
36+
- [TanStack Query Documentation](https://tanstack.com/query/latest)
37+
- [React Hook Form Documentation](https://react-hook-form.com/get-started)
38+
- [shadcn/ui Documentation](https://ui.shadcn.com/docs)
39+
- [@elek-io/core Repository](https://github.com/elek-io/core)
40+
41+
---
42+
43+
**Last Updated:** 2025-11-18
Lines changed: 148 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,212 @@
1-
# Consuming content locally
1+
# Consuming Content Locally
22

3-
Consuming created content is essential to actually benefit from a CMS. elek.io Client and Core therefore provide multiple ways of doing so.
3+
## Overview
44

5-
**Use Cases**:
5+
Once you've created content in elek.io, you probably want to consume it in your applications. elek.io Client and Core provide multiple ways to access your Project data from external applications.
66

7-
- Static site generators (Next.js, Gatsby, Hugo)
8-
- Custom build tools
9-
- Really anything you can think of
7+
**Common Use Cases**:
108

11-
## Export Project data to JSON file
9+
- **Static Site Generators**: Fetch content for Next.js, Gatsby, Astro, Hugo, etc.
10+
- **Custom Build Tools**: Integrate content into your CI/CD pipeline
11+
- **Mobile Apps**: Access content via the local API from React Native, Flutter, etc.
12+
- **Desktop Applications**: Read content from other Electron or native apps
13+
- **Documentation Sites**: Generate docs from your elek.io content
14+
- **Data Analysis**: Export content for analytics or reporting tools
1215

13-
elek.io Core can be installed globally via your package manager of choice:
16+
## Export Project Data to JSON Files
17+
18+
### Installation
19+
20+
First, install elek.io Core globally via your package manager:
1421

1522
```bash
1623
npm install -g @elek-io/core
1724
```
1825

19-
With the included CLI you can then run one of the following commands inside e.g. your websites source code directory:
26+
### Export Commands
27+
28+
The built-in CLI allows you to export Project data to JSON files. Run these commands e.g. inside your website's source code directory (or any directory where you want the exported data). Alternatively integrate them into your build scripts or CI/CD pipelines to ensure your application always has the latest content:
2029

2130
```bash
2231
# Export all Projects content to .elek.io/projects.json
2332
elek export
2433

25-
# Export one Project to .elek.io/projects.json
26-
elek export ./.elek.io [projectId]
34+
# Export one Project by ID to .elek.io/projects.json
35+
elek export ./.elek.io 467e57ea-e04a-44a7-b34b-684ed3ba6f49
2736

2837
# Export one Project to .elek.io/project-${id}.json
29-
elek export ./.elek.io [projectId]
38+
elek export ./.elek.io 467e57ea-e04a-44a7-b34b-684ed3ba6f49
3039

3140
# Export multiple Projects into separate .elek.io/project-${id}.json files
32-
elek export ./.elek.io [projectId1,projectId2] --separate
41+
elek export ./.elek.io 467e57ea-e04a-44a7-b34b-684ed3ba6f49,bcffed17-4946-4336-b420-3974d9c94a43 --separate
3342
```
3443

35-
Add the `-w` or `--watch` option to any of these commands to automatically re-export whenever a Project changes.
44+
> [!NOTE]
45+
> Replace `467e57ea-e04a-44a7-b34b-684ed3ba6f49` with your actual Project ID. You can find Project IDs in the elek.io Client UI or in your Project's `.elek.io` directory.
46+
47+
### Watch Mode
3648

37-
Then use the content inside these JSON file(s) to populate your website or application:
49+
Add the `-w` or `--watch` flag to automatically re-export whenever a Project changes:
50+
51+
```bash
52+
elek export ./.elek.io 467e57ea-e04a-44a7-b34b-684ed3ba6f49 --watch
53+
```
54+
55+
This is particularly useful during development when you're actively updating content.
56+
57+
### Using Exported JSON
58+
59+
Once exported, you can import and use the JSON data in your application:
3860

3961
```typescript
4062
import * as projects from './.elek.io/projects.json' with { type: 'json' };
4163

42-
const entries = projects['...'].collections['...'].entries;
64+
// Access a specific Project's Collections
65+
const myProject = projects['467e57ea-e04a-44a7-b34b-684ed3ba6f49'];
66+
const blogPosts = myProject.collections['blog-posts'].entries;
4367

44-
// Use the Entries
68+
// Use the Entries in your app
69+
blogPosts.forEach((post) => {
70+
console.log(post.title, post.content);
71+
});
4572
```
4673

4774
## Local API
4875

49-
Enable the local API in your User Profile of elek.io Client → "Enable Local API Server". Then you can visit `http://localhost:31310/` (or your specified port) to view a rendered OpenAPI documentation and execute queries.
76+
elek.io Core also provides a local REST API server that runs on your machine, allowing applications to query your elek.io Projects for content.
77+
78+
### Enabling the Local API
79+
80+
**Via elek.io Client**
81+
82+
1. Open elek.io Client
83+
2. Navigate to **User Profile** (top-right menu)
84+
3. Scroll to the **Local API** section
85+
4. Toggle **"Enable Local API Server"**
86+
5. Optionally change the port (default: `31310`)
87+
6. Click **Save**
88+
89+
**Via elek.io Core**
90+
91+
You can also start the local API server directly using elek.io Core CLI:
92+
93+
```bash
94+
elek api:start 31310
95+
```
96+
97+
Or programmatically in your Node.js application:
98+
99+
```typescript
100+
import ElekIoCore from '@elek-io/core';
101+
102+
const core = new ElekIoCore();
103+
core.api.start(31310);
104+
```
105+
106+
Once enabled, you can visit `http://localhost:31310/` (or your specified port) to view the OpenAPI documentation and execute test queries.
107+
108+
> [!WARNING]
109+
> Make sure the port you choose is not already in use by another application. If the API fails to start, try a different port.
50110
51-
### Generate TS/JS API Client
111+
### Generate TypeScript/JavaScript API Client
52112

53-
Of course you could write an API Client yourself but for TypeScript / JavaScript applications we provide a generated API Client with validation.
113+
While you can write an API client manually, elek.io provides a code generator that creates a type-safe client with built-in validation for TypeScript and JavaScript applications.
54114

55-
Install elek.io Core globally via your package manager of choice:
115+
#### Generate the Client
116+
117+
If you haven't already, install elek.io Core globally:
56118

57119
```bash
58120
npm install -g @elek-io/core
59121
```
60122

61-
Then use the CLI to generate a TS or JS API Client with one of the following commands:
123+
Then generate the API client:
62124

63125
```bash
64-
# Generate TS API Client with default options in ./.elek.io/client.ts
126+
# Generate TypeScript API Client with default options in ./.elek.io/client.ts
65127
elek generate:client
66128

67-
# Generate JS API Client with ESM and target ES2020 in ./.elek.io/client.ts
129+
# Generate JavaScript API Client with ESM and target ES2020
68130
elek generate:client ./.elek.io js esm es2020
69131
```
70132

71-
Then import and use the generated API Client like:
133+
#### Using the Generated Client
134+
135+
Import and use the generated API client in your application:
72136

73137
```typescript
74138
import { apiClient } from './.elek.io/client.js';
75139

76140
const client = apiClient({
77141
baseUrl: 'http://localhost:31310',
78-
apiKey: 'abc123', // Not used for now
142+
apiKey: 'abc123', // Not currently used, reserved for future authentication
79143
});
80144

81-
const entries =
82-
await client.content.v1.projects['...'].collections['...'].entries.list();
145+
// Fetch all Entries from a specific Collection
146+
const blogPosts =
147+
await client.content.v1.projects[
148+
'467e57ea-e04a-44a7-b34b-684ed3ba6f49'
149+
].collections['blog-posts'].entries.list();
150+
151+
// Access individual Entries
152+
blogPosts.forEach((post) => {
153+
console.log(post.title, post.publishedAt);
154+
});
83155
```
84156

85-
### Generate API Client for other languages
157+
### Generate API Client for Other Languages
86158

87-
For languages other than TS/JS you can either write an API Client yourself, or use an OpenAPI generator like:
159+
For languages other than TypeScript/JavaScript, you can use any OpenAPI-compatible code generator. The local API exposes its full schema at `/openapi.json`.
160+
161+
#### Example: Generate a Java Client
88162

89163
```bash
90164
npx openapi-generator-cli generate \
91165
-i http://localhost:31310/openapi.json \
92166
-g java \
93167
-o ./.elek.io/client
94168
```
169+
170+
#### Example: Generate a Python Client
171+
172+
```bash
173+
npx openapi-generator-cli generate \
174+
-i http://localhost:31310/openapi.json \
175+
-g python \
176+
-o ./.elek.io/client
177+
```
178+
179+
> [!NOTE]
180+
> Make sure the local API is running before generating the client, as the generator needs to fetch the OpenAPI schema.
181+
182+
For more generators and options, see the [OpenAPI Generator documentation](https://openapi-generator.tech/docs/generators).
183+
184+
## Troubleshooting
185+
186+
### Port Already in Use
187+
188+
If you see an error that the port is already in use:
189+
190+
1. Check which application is using the port: `lsof -i :31310` (macOS/Linux) or `netstat -ano | findstr :31310` (Windows)
191+
2. Either stop that application or choose a different port
192+
193+
### API Not Starting
194+
195+
If the local API fails to start:
196+
197+
1. Check the elek.io Client logs for error messages
198+
2. Ensure you have the latest version of elek.io Client and Core
199+
3. Try restarting elek.io Client
200+
4. Verify no firewall is blocking the port
201+
202+
### Generated Client Not Working
203+
204+
If the generated API client has type errors or runtime issues:
205+
206+
1. Regenerate the client with the latest schema
207+
2. Ensure the local API is running and accessible
208+
3. Check that your Project IDs and Collection IDs are correct
209+
210+
---
211+
212+
**Last Updated:** 2025-11-18

documentation/overview.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
# Overview
22

3-
elek.io Client is built on [Electron](https://www.electronjs.org/), to create a cross-platform desktop application with web technologies (TypeScript, React). The architecture consists of three main layers: the Main Process, the Preload Script, and the Renderer Process.
3+
## Introduction
4+
5+
elek.io Client is built on [Electron](https://www.electronjs.org/) to create a cross-platform desktop application with web technologies (TypeScript, React).
6+
7+
> [!NOTE]
8+
> By choosing Electron, we keep the languages (everything is mainly TypeScript) used throughout our repositories to a minimum and the knowledge barrier for potential contributors low. Although applications build e.g. with [Tauri](https://tauri.app/) do have a smaller bundle size and memory footprint, adding another language (Rust) would increase complexity for contributors by alot.
9+
10+
## Architecture
11+
12+
Electron applications consist of three main layers: the Main Process, the Preload Script, and the Renderer Process.
413

514
```
615
┌─────────────────────────────────────────────────────────┐
@@ -24,7 +33,7 @@ elek.io Client is built on [Electron](https://www.electronjs.org/), to create a
2433

2534
While elek.io Client provides the user interface in a desktop application, all core functionalities related to file I/O, content handling, Git operations, local read-only API hosting and CLI usage are encapsulated in the separate [@elek-io/core](https://github.com/elek-io/core) library.
2635

27-
It is used by the Main Process, since only it has access to the filesystem and Node.js APIs - the Renderer Process is sandboxed for security reasons.
36+
@elek-io/core is used by the Main Process, since only it has access to the filesystem and Node.js APIs - the Renderer Process is sandboxed for security reasons.
2837

2938
Therefore the Renderer Process communicates with the Main Process via IPC (Inter-Process Communication) to request operations via @elek-io/core.
3039

@@ -61,11 +70,11 @@ contextBridge.exposeInMainWorld('ipc', {
6170
// Renderer process uses the IPC API (src/renderer/)
6271
const project = await window.ipc.core.projects.create({
6372
name: 'My Project',
64-
description: 'A new project',
73+
description: 'A new Project',
6574
});
6675
```
6776

68-
50+ IPC Channels are available and organized by namespace.
77+
35+ IPC Channels are available and organized by namespace.
6978

7079
### Project Structure
7180

@@ -83,6 +92,7 @@ client/
8392
│ │ └── ui/ # UI components
8493
│ ├── hooks/ # React hooks
8594
│ ├── lib/ # Utilities
95+
│ ├── queries/ # Data fetching, mutations and caching
8696
│ ├── routes/ # File-based routing
8797
│ │ ├── projects/
8898
│ │ │ ├── $projectId/
@@ -98,9 +108,7 @@ client/
98108
│ │ │ └── profile.tsx
99109
│ │ └── __root.tsx
100110
│ ├── app.tsx # App entry point
101-
│ ├── ipc.ts # IPC communication
102-
│ ├── sentry.ts # Error monitoring
103-
│ └── store.ts # State management
111+
│ └── index.ts # Error monitoring and router setup
104112
├── build/ # Build resources (icons, etc.)
105113
├── documentation/ # Developer docs
106114
├── electron-builder.yml # Build configuration
@@ -111,7 +119,9 @@ client/
111119

112120
### Security
113121

114-
As mentioned, elek.io Client only allows the Renderer Process to communicate with the Main Process via a controlled IPC API exposed through the Preload Script. This follows the [security best practices of Electron](https://www.electronjs.org/docs/latest/tutorial/security) and ensures that untrusted code running in the Renderer Process (e.g. third-party libraries, users content) cannot directly access Node.js APIs or the filesystem.
122+
Handling user content that is distributed and could potentially be malicious within an app that has access to the file system, strict security is necessary. elek.io Client follows [Electron's security best practices](https://www.electronjs.org/docs/latest/tutorial/security) to create strong isolation boundaries.
123+
124+
The Renderer Process can only communicate with the Main Process via a controlled IPC API exposed through the Preload Script. This ensures that untrusted code running in the Renderer Process (e.g., third-party libraries or user content) cannot directly access Node.js APIs or the filesystem.
115125

116126
#### Renderer Process Isolation
117127

@@ -131,14 +141,28 @@ A Content Security Policy is enforced via a `<meta>` tag in the `src/renderer/in
131141

132142
#### External Content Restrictions
133143

134-
Some links to elek.io domains and loading of content are allowed in elek.io Client. To prevent abuse, the following restrictions are in place:
144+
Some links to elek.io domains and loading of content are allowed in elek.io Client. To prevent abuse and potential security risks, the following restrictions are in place:
135145

136146
**URL Whitelisting**:
137147

138-
All external requests (e.g. when a user clicks a link inside the renderer or an Asset is displayed) are checked against a whitelist. See `allowedHostnamesToLoadExternal` in [`src/main/index.ts`](/src/main/index.ts).
148+
All external requests (e.g., when a user clicks a link inside the renderer or an Asset is displayed) are checked against a whitelist of allowed hostnames:
139149

140-
Links to these hostnames are opened inside the default browser, not an elek.io Client renderer.
150+
- `elek-io-local-file://` (custom file protocol)
151+
- `localhost`
152+
- `elek.io`
153+
- `api.elek.io`
154+
- `github.com`
155+
156+
See `allowedHostnamesToLoadExternal` in [`src/main/index.ts:41-46`](/src/main/index.ts) for the implementation.
157+
158+
Links to whitelisted external hostnames are opened in the default system browser, not within an elek.io Client renderer window.
141159

142160
**Custom File Protocol**:
143161

144-
Loading of Assets in the UI is handled via a custom file protocol `elek-io-local-file://` since the standard `file://` protocol in electron has more privileges than in a browser. This ensures path validation (must be within project or tmp folders) and prevents directory traversal.
162+
Loading of Assets in the UI is handled via a custom file protocol `elek-io-local-file://` since the standard `file://` protocol in Electron has more privileges than in a browser. This custom protocol implementation ensures path validation (files must be within Project or tmp folders) and prevents directory traversal attacks.
163+
164+
See [`src/main/index.ts:267-305`](/src/main/index.ts) for the custom protocol implementation.
165+
166+
---
167+
168+
**Last Updated:** 2025-11-18

0 commit comments

Comments
 (0)