Skip to content

Commit 1a7ce05

Browse files
Copilothotlong
andcommitted
docs: update README and add migration guide from @objectql/core
- Update packages/objectql/README.md with full API documentation, exported components table, introspection types, and migration summary - Add content/docs/guides/objectql-migration.mdx with step-by-step migration instructions from @objectql/core to @objectstack/objectql - Register migration guide in guides/meta.json Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 437b0b8 commit 1a7ce05

3 files changed

Lines changed: 274 additions & 1 deletion

File tree

content/docs/guides/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"data-flow",
2121
"---Operations---",
2222
"deployment-vercel",
23+
"objectql-migration",
2324
"error-handling-client",
2425
"error-handling-server",
2526
"standards",
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
title: "Migrating from @objectql/core"
3+
description: Step-by-step guide for migrating from @objectql/core to @objectstack/objectql
4+
---
5+
6+
# Migrating from `@objectql/core` to `@objectstack/objectql`
7+
8+
Starting with `@objectstack/objectql` v3.1, all core functionality previously provided by `@objectql/core` is now available upstream. This guide walks you through migrating your project so that `@objectql/core` can be removed.
9+
10+
## Why Migrate?
11+
12+
| | `@objectql/core` (deprecated) | `@objectstack/objectql` (recommended) |
13+
| :--- | :--- | :--- |
14+
| **Engine** | Bridge class extending upstream `ObjectQL` | Canonical `ObjectQL` engine |
15+
| **Kernel Factory** | `createObjectQLKernel()` | `createObjectQLKernel()` (identical API) |
16+
| **Introspection** | `toTitleCase`, `convertIntrospectedSchemaToObjects` | Same functions, same signatures |
17+
| **Registry** | Re-exports from upstream | Direct exports |
18+
| **MetadataRegistry** | `@objectql/types` `MetadataRegistry` class | `MetadataFacade` (async `IMetadataService`) |
19+
| **Maintenance** | Planned deprecation | Actively maintained |
20+
21+
## Step 1 — Update Dependencies
22+
23+
```diff
24+
// package.json
25+
{
26+
"dependencies": {
27+
- "@objectql/core": "^4.x",
28+
- "@objectql/types": "^4.x",
29+
+ "@objectstack/objectql": "^3.1.0"
30+
}
31+
}
32+
```
33+
34+
Then re-install:
35+
36+
```bash
37+
pnpm install
38+
```
39+
40+
## Step 2 — Update Imports
41+
42+
### Engine, Repository & Context
43+
44+
```diff
45+
- import { ObjectQL, ObjectRepository, ScopedContext } from '@objectql/core';
46+
+ import { ObjectQL, ObjectRepository, ScopedContext } from '@objectstack/objectql';
47+
```
48+
49+
```diff
50+
- import type { HookHandler, HookEntry, OperationContext, EngineMiddleware } from '@objectql/core';
51+
+ import type { HookHandler, HookEntry, OperationContext, EngineMiddleware } from '@objectstack/objectql';
52+
```
53+
54+
### Schema Registry
55+
56+
```diff
57+
- import { SchemaRegistry } from '@objectql/core';
58+
+ import { SchemaRegistry } from '@objectstack/objectql';
59+
```
60+
61+
### Kernel Factory
62+
63+
```diff
64+
- import { createObjectQLKernel } from '@objectql/core';
65+
- import type { ObjectQLKernelOptions } from '@objectql/core';
66+
+ import { createObjectQLKernel } from '@objectstack/objectql';
67+
+ import type { ObjectQLKernelOptions } from '@objectstack/objectql';
68+
```
69+
70+
### Utility Functions
71+
72+
```diff
73+
- import { toTitleCase, convertIntrospectedSchemaToObjects } from '@objectql/core';
74+
+ import { toTitleCase, convertIntrospectedSchemaToObjects } from '@objectstack/objectql';
75+
```
76+
77+
### Introspection Types
78+
79+
```diff
80+
- import type { IntrospectedSchema, IntrospectedTable } from '@objectql/types';
81+
+ import type { IntrospectedSchema, IntrospectedTable } from '@objectstack/objectql';
82+
```
83+
84+
```diff
85+
- import type { IntrospectedColumn, IntrospectedForeignKey } from '@objectql/types';
86+
+ import type { IntrospectedColumn, IntrospectedForeignKey } from '@objectstack/objectql';
87+
```
88+
89+
## Step 3 — API Differences
90+
91+
### `createObjectQLKernel()`
92+
93+
The function signature is identical. The only change is the return type uses the upstream `ObjectKernel`:
94+
95+
```typescript
96+
import { createObjectQLKernel } from '@objectstack/objectql';
97+
98+
const kernel = await createObjectQLKernel({
99+
plugins: [myDriverPlugin],
100+
});
101+
await kernel.bootstrap();
102+
```
103+
104+
### `convertIntrospectedSchemaToObjects()`
105+
106+
Same signature and behavior:
107+
108+
```typescript
109+
import { convertIntrospectedSchemaToObjects } from '@objectstack/objectql';
110+
111+
const objects = convertIntrospectedSchemaToObjects(schema, {
112+
excludeTables: ['migrations'],
113+
includeTables: undefined, // optional: whitelist
114+
skipSystemColumns: true, // default: skips id, created_at, updated_at
115+
});
116+
```
117+
118+
### MetadataRegistry → MetadataFacade
119+
120+
If you were using `MetadataRegistry` from `@objectql/types`, the upstream equivalent is `MetadataFacade`. The key difference is that `MetadataFacade` methods are **async** (returns `Promise`):
121+
122+
```diff
123+
- import { MetadataRegistry } from '@objectql/types';
124+
- const registry = new MetadataRegistry();
125+
- registry.register('object', myObject);
126+
- const obj = registry.get('object', 'account');
127+
+ import { MetadataFacade } from '@objectstack/objectql';
128+
+ const facade = new MetadataFacade();
129+
+ await facade.register('object', 'account', myObject);
130+
+ const obj = await facade.get('object', 'account');
131+
```
132+
133+
### ObjectQLPlugin
134+
135+
Both packages export an `ObjectQLPlugin`, but they serve different roles:
136+
137+
| | `@objectql/core` `ObjectQLPlugin` | `@objectstack/objectql` `ObjectQLPlugin` |
138+
| :--- | :--- | :--- |
139+
| Interface | `RuntimePlugin` (from `@objectql/types`) | `Plugin` (from `@objectstack/core`) |
140+
| Role | Orchestrator composing sub-plugins (validator, formula, query) | Kernel plugin registering ObjectQL as core services |
141+
| Methods | `install()`, `onStart()`, `init()`, `start()` | `init()`, `start()` |
142+
143+
If you were using the `@objectql/core` `ObjectQLPlugin` to compose sub-plugins (`ValidatorPlugin`, `FormulaPlugin`, `QueryPlugin`), those downstream plugins are **not** part of this migration — they remain in the `@objectql` ecosystem.
144+
145+
## Step 4 — Type Mapping Reference
146+
147+
The `convertIntrospectedSchemaToObjects()` utility maps database column types as follows:
148+
149+
| Database Type | ObjectStack FieldType |
150+
| :--- | :--- |
151+
| `varchar`, `char` | `text` |
152+
| `text` | `textarea` |
153+
| `integer`, `int`, `bigint`, `smallint` | `number` |
154+
| `float`, `double`, `decimal`, `numeric`, `real` | `number` |
155+
| `boolean`, `bool` | `boolean` |
156+
| `timestamp`, `datetime` | `datetime` |
157+
| `date` | `date` |
158+
| `time` | `time` |
159+
| `json`, `jsonb` | `json` |
160+
| Foreign key column | `lookup` (with `reference` set to target table) |
161+
| _anything else_ | `text` (fallback) |
162+
163+
## Step 5 — Remove `@objectql/core`
164+
165+
Once all imports are updated and tests pass:
166+
167+
```bash
168+
pnpm remove @objectql/core @objectql/types
169+
```
170+
171+
## Checklist
172+
173+
- [ ] Replace `@objectql/core` dependency with `@objectstack/objectql` in `package.json`
174+
- [ ] Update all `import` statements (engine, registry, kernel factory, utilities, types)
175+
- [ ] Replace `MetadataRegistry` usage with `MetadataFacade` (add `await`)
176+
- [ ] Verify `ObjectQLPlugin` usage matches the upstream interface
177+
- [ ] Run `pnpm build` and fix any remaining type errors
178+
- [ ] Run `pnpm test` to verify behavior
179+
- [ ] Remove `@objectql/core` and `@objectql/types` from dependencies

packages/objectql/README.md

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,109 @@ The **Data Engine** for ObjectStack. It acts as a semantic layer between your ap
88
- **Schema Validation**: Enforces Zod schemas defined in `@objectstack/spec`.
99
- **Query Resolution**: Translates ObjectStack queries into driver-specific commands.
1010
- **Driver Architecture**: Pluggable storage (Memory, MongoDB, SQL, etc.).
11+
- **Schema Registry**: Centralized object/FQN management with multi-package ownership model.
12+
- **Kernel Factory**: One-liner kernel bootstrap with `createObjectQLKernel()`.
13+
- **Database Introspection**: Convert existing database schemas into ObjectStack metadata via `convertIntrospectedSchemaToObjects()`.
14+
- **Metadata Facade**: Injectable `IMetadataService`-compatible wrapper over SchemaRegistry.
1115

1216
## Usage
1317

18+
### Querying Data
19+
1420
```typescript
1521
import { ObjectQL } from '@objectstack/objectql';
1622

17-
// Querying data
1823
const engine = kernel.getService('objectql');
1924
const users = await engine.find('user', {
2025
where: { role: 'admin' },
2126
top: 10
2227
});
2328
```
29+
30+
### Kernel Factory
31+
32+
Create a fully wired ObjectKernel in one call:
33+
34+
```typescript
35+
import { createObjectQLKernel } from '@objectstack/objectql';
36+
37+
const kernel = await createObjectQLKernel({
38+
plugins: [myDriverPlugin, myAuthPlugin],
39+
});
40+
await kernel.bootstrap();
41+
```
42+
43+
### Database Introspection
44+
45+
Convert existing database tables into ObjectStack object definitions:
46+
47+
```typescript
48+
import { convertIntrospectedSchemaToObjects } from '@objectstack/objectql';
49+
50+
const schema = await driver.introspectSchema();
51+
const objects = convertIntrospectedSchemaToObjects(schema, {
52+
excludeTables: ['migrations', '_prisma_migrations'],
53+
});
54+
55+
for (const obj of objects) {
56+
engine.registerObject(obj);
57+
}
58+
```
59+
60+
### Schema Registry
61+
62+
```typescript
63+
import { SchemaRegistry, computeFQN } from '@objectstack/objectql';
64+
65+
// Register an object under a namespace
66+
SchemaRegistry.registerObject(taskDef, 'com.acme.todo', 'todo');
67+
68+
// Resolve FQN
69+
computeFQN('todo', 'task'); // => 'todo__task'
70+
computeFQN('base', 'user'); // => 'user' (reserved namespace)
71+
```
72+
73+
## Exported Components
74+
75+
| Export | Description |
76+
| :--- | :--- |
77+
| `ObjectQL` | Data engine implementing `IDataEngine` |
78+
| `ObjectRepository` | Scoped repository bound to object + context |
79+
| `ScopedContext` | Identity-scoped execution context with `object()` accessor |
80+
| `SchemaRegistry` | Global schema registry (FQN, ownership, package management) |
81+
| `MetadataFacade` | Async `IMetadataService`-compatible wrapper |
82+
| `ObjectQLPlugin` | Kernel plugin that registers ObjectQL services |
83+
| `ObjectStackProtocolImplementation` | Protocol implementation shim |
84+
| `createObjectQLKernel()` | Async factory returning a pre-wired `ObjectKernel` |
85+
| `toTitleCase()` | Convert `snake_case` to `Title Case` |
86+
| `convertIntrospectedSchemaToObjects()` | DB schema → `ServiceObject[]` converter |
87+
88+
### Introspection Types
89+
90+
| Type | Description |
91+
| :--- | :--- |
92+
| `IntrospectedSchema` | Top-level schema with `tables` map |
93+
| `IntrospectedTable` | Table metadata (columns, foreign keys, primary keys) |
94+
| `IntrospectedColumn` | Column metadata (name, type, nullable, maxLength, …) |
95+
| `IntrospectedForeignKey` | Foreign key relationship metadata |
96+
97+
## Migrating from `@objectql/core`
98+
99+
If you are migrating from the downstream `@objectql/core` package, see the
100+
[Migration Guide](../../content/docs/guides/objectql-migration.mdx) for
101+
step-by-step instructions.
102+
103+
**Quick summary:**
104+
105+
```diff
106+
- import { ObjectQL, SchemaRegistry, ObjectRepository } from '@objectql/core';
107+
- import { createObjectQLKernel } from '@objectql/core';
108+
- import { toTitleCase, convertIntrospectedSchemaToObjects } from '@objectql/core';
109+
+ import { ObjectQL, SchemaRegistry, ObjectRepository } from '@objectstack/objectql';
110+
+ import { createObjectQLKernel } from '@objectstack/objectql';
111+
+ import { toTitleCase, convertIntrospectedSchemaToObjects } from '@objectstack/objectql';
112+
```
113+
114+
## License
115+
116+
Apache-2.0 © ObjectStack

0 commit comments

Comments
 (0)