ts-typed-api 0.1.14 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/openapi.js CHANGED
@@ -98,7 +98,7 @@ function generateOpenApiSpec(definitions, options = {}) {
98
98
  };
99
99
  // Register the route with the registry
100
100
  // The path needs to be transformed from Express-style (:param) to OpenAPI-style ({param})
101
- const openApiPath = route.path.replace(/:(\w+)/g, '{$1}');
101
+ const openApiPath = `/${definition.prefix ?? ''}${route.path}`.replace(/\/+/g, '/').replace(/:(\w+)/g, '{$1}');
102
102
  registry.registerPath({
103
103
  method: route.method.toLowerCase(), // Ensure method is lowercase
104
104
  path: openApiPath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-typed-api",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "A lightweight, type-safe RPC library for TypeScript with Zod validation",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/openapi.ts CHANGED
@@ -116,7 +116,7 @@ export function generateOpenApiSpec(
116
116
 
117
117
  // Register the route with the registry
118
118
  // The path needs to be transformed from Express-style (:param) to OpenAPI-style ({param})
119
- const openApiPath = route.path.replace(/:(\w+)/g, '{$1}');
119
+ const openApiPath = `/${definition.prefix ?? ''}${route.path}`.replace(/\/+/g, '/').replace(/:(\w+)/g, '{$1}');
120
120
 
121
121
  registry.registerPath({
122
122
  method: route.method.toLowerCase() as any, // Ensure method is lowercase
@@ -0,0 +1,86 @@
1
+ import { describe, test, expect } from '@jest/globals';
2
+ import { generateOpenApiSpec } from '../src/openapi';
3
+ import { PublicApiDefinition } from '../examples/simple/definitions';
4
+ import { PrivateApiDefinition } from '../examples/simple/definitions';
5
+ import { z } from 'zod';
6
+ import { CreateApiDefinition } from '../src/definition';
7
+
8
+ describe('OpenAPI Specification Generation', () => {
9
+ test('should generate OpenAPI spec for a single definition', () => {
10
+ const spec = generateOpenApiSpec(PublicApiDefinition);
11
+
12
+ expect(spec).toBeDefined();
13
+ expect(spec.openapi).toBe('3.0.0');
14
+ expect(spec.info).toBeDefined();
15
+ expect(spec.paths).toBeDefined();
16
+ });
17
+
18
+ test('should generate OpenAPI spec for multiple definitions', () => {
19
+ const spec = generateOpenApiSpec([PublicApiDefinition, PrivateApiDefinition]);
20
+
21
+ expect(spec).toBeDefined();
22
+ expect(spec.openapi).toBe('3.0.0');
23
+ expect(spec.info).toBeDefined();
24
+ expect(spec.paths).toBeDefined();
25
+
26
+ // Verify paths from both definitions are included
27
+ const publicPaths = Object.keys(spec.paths ?? {}).filter(path =>
28
+ path.includes('/public/')
29
+ );
30
+ const privatePaths = Object.keys(spec.paths ?? {}).filter(path =>
31
+ path.includes('/private/')
32
+ );
33
+
34
+ expect(publicPaths.length).toBeGreaterThan(0);
35
+ expect(privatePaths.length).toBeGreaterThan(0);
36
+ });
37
+
38
+ test('should handle custom OpenAPI spec options', () => {
39
+ const spec = generateOpenApiSpec(PublicApiDefinition, {
40
+ info: {
41
+ title: 'Test API',
42
+ version: '2.0.0',
43
+ description: 'A test API description'
44
+ },
45
+ servers: [{ url: 'https://api.example.com', description: 'Production server' }]
46
+ });
47
+
48
+ expect(spec.info.title).toBe('Test API');
49
+ expect(spec.info.version).toBe('2.0.0');
50
+ expect(spec.info.description).toBe('A test API description');
51
+ expect(spec.servers?.[0]?.url).toBe('https://api.example.com');
52
+ });
53
+
54
+ test('should handle complex Zod schemas', () => {
55
+ // Create a complex Zod schema to test schema registration
56
+ const ComplexSchema = z.object({
57
+ id: z.string().uuid(),
58
+ name: z.string().min(3).max(50),
59
+ age: z.number().int().positive(),
60
+ metadata: z.record(z.string(), z.unknown()).optional(),
61
+ tags: z.array(z.string()).optional()
62
+ });
63
+
64
+ const TestDefinition = CreateApiDefinition({
65
+ endpoints: {
66
+ test: {
67
+ complexEndpoint: {
68
+ method: 'POST' as const,
69
+ path: '/test/complex',
70
+ body: ComplexSchema,
71
+ responses: {
72
+ 200: ComplexSchema,
73
+ 422: z.object({ error: z.string() })
74
+ }
75
+ }
76
+ }
77
+ }
78
+ });
79
+
80
+ const spec = generateOpenApiSpec(TestDefinition);
81
+
82
+ expect(spec).toBeDefined();
83
+ expect(spec.components).toBeDefined();
84
+ expect(spec.components?.schemas).toBeDefined();
85
+ });
86
+ });