Skip to content

Commit 8202582

Browse files
authored
Merge pull request #1007 from objectstack-ai/copilot/fix-ci-build-and-test-errors-yet-again
2 parents 61429f5 + 321cd28 commit 8202582

File tree

8 files changed

+46
-28
lines changed

8 files changed

+46
-28
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
- **ObjectQL build failure** — Fixed TypeScript TS2345 errors in `packages/objectql/src/protocol.ts`
12+
where `SchemaRegistry.registerItem()` calls failed type checking for the `keyField` parameter.
13+
Applied `'name' as any` cast consistent with the established codebase pattern.
14+
- **ObjectQL `loadMetaFromDb`** — Fixed metadata hydration for `object` type records to use
15+
`SchemaRegistry.registerObject()` instead of `registerItem()`, resolving a mismatch where
16+
objects registered via `registerItem` could not be retrieved via `getItem('object', ...)`.
17+
- **Adapter discovery endpoints** — Fixed discovery route in Hono, SvelteKit, Nuxt, Next.js,
18+
and Fastify adapters to serve discovery info at the API prefix root (e.g., `GET /api`)
19+
instead of a `/discovery` subpath. Updated `.well-known/objectstack` redirects accordingly.
20+
- **Client feed namespace routing** — Fixed `ObjectStackClient.feed` methods to use the `data`
21+
route (`/api/v1/data/{object}/{recordId}/feed`) instead of a separate `/api/v1/feed` route,
22+
matching the actual server-side routing where feed is a sub-resource of data.
23+
1024
### Added
1125
- **`@objectstack/service-ai` — Unified AI capability service plugin** — New kernel plugin
1226
providing standardized AI service integration:

packages/adapters/fastify/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ export async function objectStackPlugin(fastify: FastifyInstance, options: Fasti
7676
// ─── Explicit routes (framework-specific handling required) ────────────────
7777

7878
// --- Discovery ---
79-
fastify.get(`${prefix}/discovery`, async (_request: FastifyRequest, reply: FastifyReply) => {
79+
fastify.get(prefix, async (_request: FastifyRequest, reply: FastifyReply) => {
8080
return reply.send({ data: await dispatcher.getDiscoveryInfo(prefix) });
8181
});
8282

8383
// --- .well-known ---
8484
fastify.get('/.well-known/objectstack', async (_request: FastifyRequest, reply: FastifyReply) => {
85-
return reply.redirect(`${prefix}/discovery`);
85+
return reply.redirect(prefix);
8686
});
8787

8888
// --- Auth (needs auth service integration) ---

packages/adapters/hono/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ export function createHonoApp(options: ObjectStackHonoOptions): Hono {
8181
// ─── Explicit routes (framework-specific handling required) ────────────────
8282

8383
// --- Discovery ---
84-
app.get(`${prefix}/discovery`, async (c) => {
84+
app.get(prefix, async (c) => {
8585
return c.json({ data: await dispatcher.getDiscoveryInfo(prefix) });
8686
});
8787

8888
// --- .well-known ---
8989
app.get('/.well-known/objectstack', (c) => {
90-
return c.redirect(`${prefix}/discovery`);
90+
return c.redirect(prefix);
9191
});
9292

9393
// --- Auth (needs auth service integration) ---

packages/adapters/nextjs/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export function createRouteHandler(options: NextAdapterOptions) {
6262
const method = req.method;
6363

6464
// --- 0. Discovery Endpoint ---
65-
if (segments.length === 1 && segments[0] === 'discovery' && method === 'GET') {
65+
if (segments.length === 0 && method === 'GET') {
6666
return NextResponse.json({ data: await dispatcher.getDiscoveryInfo(options.prefix || '/api') });
6767
}
6868

@@ -152,7 +152,7 @@ export function createDiscoveryHandler(options: NextAdapterOptions) {
152152
return async function discoveryHandler(req: NextRequest) {
153153
const apiPath = options.prefix || '/api';
154154
const url = new URL(req.url);
155-
const targetUrl = new URL(`${apiPath}/discovery`, url.origin);
155+
const targetUrl = new URL(apiPath, url.origin);
156156
return NextResponse.redirect(targetUrl);
157157
}
158158
}

packages/adapters/nuxt/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export function createH3Router(options: NuxtAdapterOptions): Router {
8989

9090
// --- Discovery ---
9191
router.get(
92-
`${prefix}/discovery`,
92+
prefix,
9393
defineEventHandler(async () => {
9494
return { data: await dispatcher.getDiscoveryInfo(prefix) };
9595
}),
@@ -99,7 +99,7 @@ export function createH3Router(options: NuxtAdapterOptions): Router {
9999
router.get(
100100
'/.well-known/objectstack',
101101
defineEventHandler((event) => {
102-
return sendRedirect(event, `${prefix}/discovery`);
102+
return sendRedirect(event, prefix);
103103
}),
104104
);
105105

packages/adapters/sveltekit/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export function createRequestHandler(options: SvelteKitAdapterOptions) {
9999
const segments = path.split('/').filter(Boolean);
100100

101101
// --- Discovery ---
102-
if (segments.length === 1 && segments[0] === 'discovery' && method === 'GET') {
102+
if (segments.length === 0 && method === 'GET') {
103103
return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {
104104
status: 200,
105105
headers: { 'Content-Type': 'application/json' },

packages/client/src/index.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,7 @@ export class ObjectStackClient {
12941294
* List feed items for a record
12951295
*/
12961296
list: async (object: string, recordId: string, options?: { type?: string; limit?: number; cursor?: string }): Promise<GetFeedResponse> => {
1297-
const route = this.getRoute('feed');
1297+
const route = this.getRoute('data');
12981298
const params = new URLSearchParams();
12991299
if (options?.type) params.set('type', options.type);
13001300
if (options?.limit) params.set('limit', String(options.limit));
@@ -1308,7 +1308,7 @@ export class ObjectStackClient {
13081308
* Create a new feed item (comment, note, task, etc.)
13091309
*/
13101310
create: async (object: string, recordId: string, data: { type: string; body?: string; mentions?: any[]; parentId?: string; visibility?: string }): Promise<CreateFeedItemResponse> => {
1311-
const route = this.getRoute('feed');
1311+
const route = this.getRoute('data');
13121312
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed`, {
13131313
method: 'POST',
13141314
body: JSON.stringify(data)
@@ -1320,7 +1320,7 @@ export class ObjectStackClient {
13201320
* Update an existing feed item
13211321
*/
13221322
update: async (object: string, recordId: string, feedId: string, data: { body?: string; mentions?: any[]; visibility?: string }): Promise<UpdateFeedItemResponse> => {
1323-
const route = this.getRoute('feed');
1323+
const route = this.getRoute('data');
13241324
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}`, {
13251325
method: 'PUT',
13261326
body: JSON.stringify(data)
@@ -1332,7 +1332,7 @@ export class ObjectStackClient {
13321332
* Delete a feed item
13331333
*/
13341334
delete: async (object: string, recordId: string, feedId: string): Promise<DeleteFeedItemResponse> => {
1335-
const route = this.getRoute('feed');
1335+
const route = this.getRoute('data');
13361336
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}`, {
13371337
method: 'DELETE'
13381338
});
@@ -1343,7 +1343,7 @@ export class ObjectStackClient {
13431343
* Add an emoji reaction to a feed item
13441344
*/
13451345
addReaction: async (object: string, recordId: string, feedId: string, emoji: string): Promise<AddReactionResponse> => {
1346-
const route = this.getRoute('feed');
1346+
const route = this.getRoute('data');
13471347
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}/reactions`, {
13481348
method: 'POST',
13491349
body: JSON.stringify({ emoji })
@@ -1355,7 +1355,7 @@ export class ObjectStackClient {
13551355
* Remove an emoji reaction from a feed item
13561356
*/
13571357
removeReaction: async (object: string, recordId: string, feedId: string, emoji: string): Promise<RemoveReactionResponse> => {
1358-
const route = this.getRoute('feed');
1358+
const route = this.getRoute('data');
13591359
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}/reactions/${encodeURIComponent(emoji)}`, {
13601360
method: 'DELETE'
13611361
});
@@ -1366,7 +1366,7 @@ export class ObjectStackClient {
13661366
* Pin a feed item to the top of the timeline
13671367
*/
13681368
pin: async (object: string, recordId: string, feedId: string): Promise<PinFeedItemResponse> => {
1369-
const route = this.getRoute('feed');
1369+
const route = this.getRoute('data');
13701370
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}/pin`, {
13711371
method: 'POST'
13721372
});
@@ -1377,7 +1377,7 @@ export class ObjectStackClient {
13771377
* Unpin a feed item
13781378
*/
13791379
unpin: async (object: string, recordId: string, feedId: string): Promise<UnpinFeedItemResponse> => {
1380-
const route = this.getRoute('feed');
1380+
const route = this.getRoute('data');
13811381
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}/pin`, {
13821382
method: 'DELETE'
13831383
});
@@ -1388,7 +1388,7 @@ export class ObjectStackClient {
13881388
* Star (bookmark) a feed item
13891389
*/
13901390
star: async (object: string, recordId: string, feedId: string): Promise<StarFeedItemResponse> => {
1391-
const route = this.getRoute('feed');
1391+
const route = this.getRoute('data');
13921392
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}/star`, {
13931393
method: 'POST'
13941394
});
@@ -1399,7 +1399,7 @@ export class ObjectStackClient {
13991399
* Unstar a feed item
14001400
*/
14011401
unstar: async (object: string, recordId: string, feedId: string): Promise<UnstarFeedItemResponse> => {
1402-
const route = this.getRoute('feed');
1402+
const route = this.getRoute('data');
14031403
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/feed/${encodeURIComponent(feedId)}/star`, {
14041404
method: 'DELETE'
14051405
});
@@ -1410,7 +1410,7 @@ export class ObjectStackClient {
14101410
* Search feed items
14111411
*/
14121412
search: async (object: string, recordId: string, query: string, options?: { type?: string; actorId?: string; dateFrom?: string; dateTo?: string; limit?: number; cursor?: string }): Promise<SearchFeedResponse> => {
1413-
const route = this.getRoute('feed');
1413+
const route = this.getRoute('data');
14141414
const params = new URLSearchParams();
14151415
params.set('query', query);
14161416
if (options?.type) params.set('type', options.type);
@@ -1427,7 +1427,7 @@ export class ObjectStackClient {
14271427
* Get field-level changelog for a record
14281428
*/
14291429
getChangelog: async (object: string, recordId: string, options?: { field?: string; actorId?: string; dateFrom?: string; dateTo?: string; limit?: number; cursor?: string }): Promise<GetChangelogResponse> => {
1430-
const route = this.getRoute('feed');
1430+
const route = this.getRoute('data');
14311431
const params = new URLSearchParams();
14321432
if (options?.field) params.set('field', options.field);
14331433
if (options?.actorId) params.set('actorId', options.actorId);
@@ -1444,7 +1444,7 @@ export class ObjectStackClient {
14441444
* Subscribe to record notifications
14451445
*/
14461446
subscribe: async (object: string, recordId: string, options?: { events?: string[]; channels?: string[] }): Promise<SubscribeResponse> => {
1447-
const route = this.getRoute('feed');
1447+
const route = this.getRoute('data');
14481448
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/subscribe`, {
14491449
method: 'POST',
14501450
body: JSON.stringify(options || {})
@@ -1456,7 +1456,7 @@ export class ObjectStackClient {
14561456
* Unsubscribe from record notifications
14571457
*/
14581458
unsubscribe: async (object: string, recordId: string): Promise<UnsubscribeResponse> => {
1459-
const route = this.getRoute('feed');
1459+
const route = this.getRoute('data');
14601460
const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/subscribe`, {
14611461
method: 'DELETE'
14621462
});

packages/objectql/src/protocol.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
205205
? JSON.parse(record.metadata)
206206
: record.metadata;
207207
// Hydrate back into registry
208-
SchemaRegistry.registerItem(request.type, data, 'name');
208+
SchemaRegistry.registerItem(request.type, data, 'name' as any);
209209
return data;
210210
});
211211
} else {
@@ -219,7 +219,7 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
219219
const data = typeof record.metadata === 'string'
220220
? JSON.parse(record.metadata)
221221
: record.metadata;
222-
SchemaRegistry.registerItem(request.type, data, 'name');
222+
SchemaRegistry.registerItem(request.type, data, 'name' as any);
223223
return data;
224224
});
225225
}
@@ -254,7 +254,7 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
254254
? JSON.parse(record.metadata)
255255
: record.metadata;
256256
// Hydrate back into registry for next time
257-
SchemaRegistry.registerItem(request.type, item, 'name');
257+
SchemaRegistry.registerItem(request.type, item, 'name' as any);
258258
} else {
259259
// Try alternate type name
260260
const alt = request.type.endsWith('s') ? request.type.slice(0, -1) : request.type + 's';
@@ -266,7 +266,7 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
266266
? JSON.parse(altRecord.metadata)
267267
: altRecord.metadata;
268268
// Hydrate back into registry for next time
269-
SchemaRegistry.registerItem(request.type, item, 'name');
269+
SchemaRegistry.registerItem(request.type, item, 'name' as any);
270270
}
271271
}
272272
} catch {
@@ -980,7 +980,11 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
980980
const data = typeof record.metadata === 'string'
981981
? JSON.parse(record.metadata)
982982
: record.metadata;
983-
SchemaRegistry.registerItem(record.type, data, 'name');
983+
if (record.type === 'object') {
984+
SchemaRegistry.registerObject(data as any, record.packageId || 'sys_metadata');
985+
} else {
986+
SchemaRegistry.registerItem(record.type, data, 'name' as any);
987+
}
984988
loaded++;
985989
} catch (e) {
986990
errors++;

0 commit comments

Comments
 (0)