Skip to content

Commit a92d0c0

Browse files
authored
Merge branch 'copilot/add-http-server-implementation' into copilot/update-codebase-references
2 parents cf4f562 + 54e3d9d commit a92d0c0

8 files changed

Lines changed: 79 additions & 23 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: View
3+
description: View protocol schemas
4+
---
5+
6+
# View
7+
8+
<Callout type="info">
9+
**Source:** `packages/spec/src/api/view.zod.ts`
10+
</Callout>
11+
12+
## TypeScript Usage
13+
14+
```typescript
15+
import { HttpMethodSchema } from '@objectstack/spec/api';
16+
import type { HttpMethod } from '@objectstack/spec/api';
17+
18+
// Validate data
19+
const result = HttpMethodSchema.parse(data);
20+
```
21+
22+
---
23+
24+
## HttpMethod
25+
26+
### Allowed Values
27+
28+
* `GET`
29+
* `POST`
30+
* `PUT`
31+
* `DELETE`
32+
* `PATCH`
33+
* `HEAD`
34+
* `OPTIONS`
35+

examples/rest-server-example.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* generate RESTful CRUD endpoints for your ObjectStack application.
66
*/
77

8-
import { RestServer, HttpServer } from '@objectstack/runtime';
8+
import { RestServer } from '@objectstack/runtime';
99
import type { IProtocolProvider } from '@objectstack/runtime';
1010

1111
/**

packages/runtime/src/http-server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IHttpServer, IHttpRequest, IHttpResponse, RouteHandler, Middleware } from '@objectstack/core';
1+
import { IHttpServer, RouteHandler, Middleware } from '@objectstack/core';
22

33
/**
44
* HttpServer - Unified HTTP Server Abstraction

packages/runtime/src/rest-server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IHttpServer, RouteHandler } from '@objectstack/core';
1+
import { IHttpServer } from '@objectstack/core';
22
import { RouteManager } from './route-manager';
33
import { RestServerConfig, CrudOperation, RestApiConfig, CrudEndpointsConfig, MetadataEndpointsConfig, BatchEndpointsConfig, RouteGenerationConfig } from '@objectstack/spec/api';
44
import { ObjectStackProtocol } from '@objectstack/spec/api';
@@ -295,7 +295,7 @@ export class RestServer {
295295
});
296296

297297
if (result.notModified) {
298-
res.status(304).json({});
298+
res.status(304).send();
299299
return;
300300
}
301301

packages/runtime/src/route-manager.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,16 @@ export class RouteManager {
6161
* @param entry - Route entry with method, path, handler, and metadata
6262
*/
6363
register(entry: Omit<RouteEntry, 'handler'> & { handler: RouteHandler | string }): void {
64-
const handler = typeof entry.handler === 'string'
65-
? this.resolveHandler(entry.handler)
66-
: entry.handler;
64+
// Validate handler type - string handlers not yet supported
65+
if (typeof entry.handler === 'string') {
66+
throw new Error(
67+
`String-based route handlers are not supported yet. ` +
68+
`Received handler identifier "${entry.handler}". ` +
69+
`Please provide a RouteHandler function instead.`
70+
);
71+
}
72+
73+
const handler: RouteHandler = entry.handler;
6774

6875
const routeEntry: RouteEntry = {
6976
method: entry.method,
@@ -200,13 +207,6 @@ export class RouteManager {
200207
throw new Error(`Unsupported HTTP method: ${method}`);
201208
}
202209
}
203-
204-
/**
205-
* Resolve handler by name (placeholder for future handler registry)
206-
*/
207-
private resolveHandler(handlerName: string): RouteHandler {
208-
throw new Error(`Handler resolution not implemented: ${handlerName}`);
209-
}
210210
}
211211

212212
/**
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"$ref": "#/definitions/HttpMethod",
3+
"definitions": {
4+
"HttpMethod": {
5+
"type": "string",
6+
"enum": [
7+
"GET",
8+
"POST",
9+
"PUT",
10+
"DELETE",
11+
"PATCH",
12+
"HEAD",
13+
"OPTIONS"
14+
]
15+
}
16+
},
17+
"$schema": "http://json-schema.org/draft-07/schema#"
18+
}

packages/spec/src/api/router.zod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { z } from 'zod';
22
import { CorsConfigSchema, StaticMountSchema, HttpMethod } from '../shared/http.zod';
33

4+
// Re-export HttpMethod for convenience
5+
export { HttpMethod };
6+
47
/**
58
* Route Category Enum
69
* Classifies routes for middleware application and security policies.

packages/spec/src/data/external-lookup.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { describe, it, expect } from 'vitest';
22
import {
33
ExternalDataSourceSchema,
4-
FieldMappingSchema,
4+
ExternalFieldMappingSchema,
55
ExternalLookupSchema,
66
type ExternalLookup,
77
type ExternalDataSource,
8-
type FieldMapping,
8+
type ExternalFieldMapping,
99
} from './external-lookup.zod';
1010

1111
describe('ExternalDataSourceSchema', () => {
@@ -118,16 +118,16 @@ describe('ExternalDataSourceSchema', () => {
118118
});
119119
});
120120

121-
describe('FieldMappingSchema', () => {
121+
describe('ExternalFieldMappingSchema', () => {
122122
it('should validate complete field mapping', () => {
123-
const validMapping: FieldMapping = {
123+
const validMapping: ExternalFieldMapping = {
124124
source: 'AccountName',
125125
target: 'name',
126126
type: 'text',
127127
readonly: true,
128128
};
129129

130-
expect(() => FieldMappingSchema.parse(validMapping)).not.toThrow();
130+
expect(() => ExternalFieldMappingSchema.parse(validMapping)).not.toThrow();
131131
});
132132

133133
it('should accept minimal field mapping', () => {
@@ -137,7 +137,7 @@ describe('FieldMappingSchema', () => {
137137
type: 'text',
138138
};
139139

140-
expect(() => FieldMappingSchema.parse(minimalMapping)).not.toThrow();
140+
expect(() => ExternalFieldMappingSchema.parse(minimalMapping)).not.toThrow();
141141
});
142142

143143
it('should default readonly to true', () => {
@@ -147,7 +147,7 @@ describe('FieldMappingSchema', () => {
147147
type: 'text',
148148
};
149149

150-
const parsed = FieldMappingSchema.parse(mapping);
150+
const parsed = ExternalFieldMappingSchema.parse(mapping);
151151
expect(parsed.readonly).toBe(true);
152152
});
153153

@@ -159,7 +159,7 @@ describe('FieldMappingSchema', () => {
159159
readonly: false,
160160
};
161161

162-
expect(() => FieldMappingSchema.parse(writableMapping)).not.toThrow();
162+
expect(() => ExternalFieldMappingSchema.parse(writableMapping)).not.toThrow();
163163
});
164164

165165
it('should accept various field types', () => {
@@ -172,7 +172,7 @@ describe('FieldMappingSchema', () => {
172172
type,
173173
};
174174

175-
expect(() => FieldMappingSchema.parse(mapping)).not.toThrow();
175+
expect(() => ExternalFieldMappingSchema.parse(mapping)).not.toThrow();
176176
});
177177
});
178178
});

0 commit comments

Comments
 (0)