Skip to content

Commit cf9f169

Browse files
committed
Add hello-world starter example with zero-config setup and inline schema
1 parent 1fb9831 commit cf9f169

File tree

9 files changed

+220
-119
lines changed

9 files changed

+220
-119
lines changed

README.md

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -46,57 +46,54 @@ ObjectQL is organized as a Monorepo to ensure modularity and universal compatibi
4646
### 1. Installation
4747

4848
```bash
49-
# Install core and a driver (e.g., Postgres)
50-
npm install @objectql/core @objectql/driver-sql pg
51-
49+
# Install core and a driver (e.g., Postgres or SQLite)
50+
npm install @objectql/core @objectql/driver-sql sqlite3
5251
```
5352

54-
### 2. Define Schema (The "Object")
53+
### 2. The Universal Script
5554

56-
Create a simple definition object (or load it from a `.yml` file).
57-
58-
```typescript
59-
const UserObject = {
60-
name: "users",
61-
fields: {
62-
name: { type: "text", required: true },
63-
email: { type: "email", unique: true },
64-
role: {
65-
type: "select",
66-
options: ["admin", "user"],
67-
default: "user"
68-
}
69-
}
70-
};
71-
72-
```
73-
74-
### 3. Initialize & Query
75-
76-
ObjectQL provides a unified API regardless of the underlying database.
55+
ObjectQL can run in a single file without complex configuration.
7756

7857
```typescript
7958
import { ObjectQL } from '@objectql/core';
8059
import { SqlDriver } from '@objectql/driver-sql';
8160

8261
async function main() {
83-
// 1. Initialize Engine
84-
const objectql = new ObjectQL();
85-
86-
// 2. Register Driver
62+
// 1. Initialize Driver (In-Memory SQLite)
8763
const driver = new SqlDriver({
88-
connection: process.env.DATABASE_URL
64+
client: 'sqlite3',
65+
connection: { filename: ':memory:' },
66+
useNullAsDefault: true
8967
});
90-
objectql.registerDriver(driver);
9168

92-
// 3. Register Object
93-
objectql.register(UserObject);
69+
// 2. Initialize Engine
70+
const app = new ObjectQL({
71+
datasources: { default: driver }
72+
});
73+
74+
// 3. Define Schema (The "Object")
75+
// In a real app, this would be loaded from a .yml file
76+
app.registerObject({
77+
name: "users",
78+
fields: {
79+
name: { type: "text", required: true },
80+
email: { type: "email", unique: true },
81+
role: {
82+
type: "select",
83+
options: ["admin", "user"],
84+
defaultValue: "user"
85+
}
86+
}
87+
});
88+
89+
await app.init();
9490

9591
// 4. Enjoy Type-Safe(ish) CRUD
96-
const repo = objectql.getRepository('users');
92+
const ctx = app.createContext({ isSystem: true });
93+
const repo = ctx.object('users');
9794

9895
// Create
99-
await repo.insert({ name: 'Alice', email: 'alice@example.com' });
96+
await repo.create({ name: 'Alice', email: 'alice@example.com' });
10097

10198
// Find
10299
const users = await repo.find({
@@ -107,7 +104,6 @@ async function main() {
107104
}
108105

109106
main();
110-
111107
```
112108

113109
---
@@ -176,5 +172,3 @@ You can use it freely in personal, commercial, or open-source projects.
176172

177173
<sub><b>ObjectQL (Data)</b> • <a href="https://github.com/objectql/objectos">ObjectOS (System)</a> • <a href="https://github.com/objectql/objectui">Object UI (View)</a></sub>
178174
</div>
179-
180-
```

docs/guide/getting-started.md

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,67 @@ npm install @objectql/core @objectql/driver-mongo mongodb
2020

2121
## Quick Start: The "Hello World"
2222

23-
Let's build a simple **To-Do List** backend.
23+
You can experience ObjectQL with a single file. No YAML, no complex config.
2424

25-
### 1. Define Your Object
25+
### 1. Minimal Setup
2626

27-
In ObjectQL, everything is an "Object" (like a Table or Collection).
27+
Install the core and SQLite driver (for zero-config database).
2828

29-
**ObjectQL uses filename-based identification** - the object name is automatically inferred from the filename, making your metadata files cleaner.
29+
```bash
30+
npm install @objectql/core @objectql/driver-sql sqlite3
31+
# or
32+
pnpm add @objectql/core @objectql/driver-sql sqlite3
33+
```
3034

31-
```yaml
32-
# File: todo.object.yml
33-
# Object name "todo" is automatically inferred from filename!
35+
### 2. The Universal Script
3436

35-
label: To-Do Item
36-
fields:
37-
title:
38-
type: text
39-
label: Task Name
40-
completed:
41-
type: boolean
42-
default: false
43-
```
37+
Create `index.ts`. This script defines the schema, boots the engine, and runs queries in one go.
38+
39+
```typescript
40+
import { ObjectQL } from '@objectql/core';
41+
import { SqlDriver } from '@objectql/driver-sql';
42+
43+
async function main() {
44+
// 1. Initialize Driver (In-Memory SQLite)
45+
const driver = new SqlDriver({
46+
client: 'sqlite3',
47+
connection: { filename: ':memory:' },
48+
useNullAsDefault: true
49+
});
50+
51+
// 2. Initialize Engine
52+
const app = new ObjectQL({
53+
datasources: { default: driver }
54+
});
55+
56+
// 3. Define Metadata Inline (Code as Configuration)
57+
app.registerObject({
58+
name: 'todo',
59+
fields: {
60+
title: { type: 'text', required: true },
61+
completed: { type: 'boolean', defaultValue: false }
62+
}
63+
});
64+
65+
await app.init();
66+
67+
// 4. Run Business Logic
68+
// We use a system context here for simplicity
69+
const ctx = app.createContext({ isSystem: true });
70+
const repo = ctx.object('todo');
4471

45-
**Note:** You no longer need to specify `name: todo` - it's inferred from the filename `todo.object.yml`!
72+
await repo.create({ title: 'Build the Future' });
73+
74+
const results = await repo.find();
75+
console.log('Todos:', results);
76+
}
77+
78+
main();
79+
```
4680

47-
### 2. Configure the Engine
81+
## Scaling Up: The Metadata Approach
4882

49-
Updated in v0.2: You can now use a simple connection string.
83+
Once you are comfortable with the core, you should move your definitions to YAML files.
5084

5185
```typescript
5286
import { ObjectQL } from '@objectql/core';

examples/graphql-api/README.md

Lines changed: 0 additions & 62 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Hello ObjectQL
2+
3+
This is the simplest possible example of **ObjectQL**.
4+
5+
It demonstrates:
6+
1. **Zero Config:** No YAML files or server setup required.
7+
2. **In-Memory SQL:** Uses SQLite in memory, so no database installation is needed.
8+
3. **Inline Schema:** Defines the data model directly in code.
9+
10+
## How to Run
11+
12+
Since you are in the monorepo, simply run:
13+
14+
```bash
15+
# Install dependencies (if not already done at root)
16+
pnpm install
17+
18+
# Run the script
19+
cd examples/starters/hello-world
20+
pnpm start
21+
```
22+
23+
## What you see
24+
25+
The script will:
26+
1. Initialize the ObjectQL engine.
27+
2. Create a `deal` object definition on the fly.
28+
3. Insert a record into the in-memory SQLite database.
29+
4. Query it back and print the result.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { ObjectQL } from '@objectql/core';
2+
import { SqlDriver } from '@objectql/driver-sql';
3+
4+
async function main() {
5+
console.log("🚀 Starting ObjectQL Hello World...");
6+
7+
// 1. Initialize Driver
8+
const driver = new SqlDriver({
9+
client: 'sqlite3',
10+
connection: { filename: ':memory:' },
11+
useNullAsDefault: true
12+
});
13+
14+
// 2. Initialize Engine (Pass driver in config)
15+
const app = new ObjectQL({
16+
datasources: {
17+
default: driver
18+
}
19+
});
20+
21+
// 3. Define Metadata Inline
22+
app.registerObject({
23+
name: 'deal',
24+
fields: {
25+
title: { type: 'text', required: true },
26+
amount: { type: 'currency', scale: 2 },
27+
stage: {
28+
type: 'select',
29+
options: ['new', 'negotiation', 'closed'],
30+
defaultValue: 'new'
31+
}
32+
}
33+
});
34+
35+
await app.init(); // Boot the engine
36+
37+
// 4. Run Business Logic
38+
// We create a system context to bypass permission checks for this simple script
39+
const ctx = app.createContext({ isSystem: true });
40+
const repo = ctx.object('deal');
41+
42+
console.log("Creating a new Deal...");
43+
await repo.create({
44+
title: 'Enterprise Contract',
45+
amount: 50000,
46+
stage: 'new'
47+
});
48+
49+
const results = await repo.find({});
50+
console.log('✅ Deals found in database:', results);
51+
}
52+
53+
main().catch(console.error);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@example/hello-world",
3+
"version": "1.0.0",
4+
"private": true,
5+
"description": "Zero-config ObjectQL starter",
6+
"scripts": {
7+
"start": "tsx index.ts"
8+
},
9+
"dependencies": {
10+
"@objectql/core": "workspace:*",
11+
"@objectql/driver-sql": "workspace:*",
12+
"sqlite3": "^5.1.7"
13+
},
14+
"devDependencies": {
15+
"tsx": "^4.7.1",
16+
"typescript": "^5.3.3",
17+
"@types/node": "^20.11.24"
18+
}
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"module": "Start",
5+
"moduleResolution": "node",
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"skipLibCheck": true,
9+
"forceConsistentCasingInFileNames": true
10+
}
11+
}

pnpm-lock.yaml

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)