@capixjs/transport-rest 0.1.0-alpha.12 → 0.1.0-alpha.14
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/coercion.d.ts.map +1 -1
- package/dist/coercion.js +20 -19
- package/dist/coercion.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts +45 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +196 -0
- package/dist/openapi.js.map +1 -0
- package/dist/serializer.d.ts +1 -1
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +6 -5
- package/dist/serializer.js.map +1 -1
- package/package.json +3 -4
package/dist/coercion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coercion.d.ts","sourceRoot":"","sources":["../src/coercion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"coercion.d.ts","sourceRoot":"","sources":["../src/coercion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;AAqElE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,YAAY,CAkB5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CASpE;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GACxC,IAAI,CAKN"}
|
package/dist/coercion.js
CHANGED
|
@@ -15,25 +15,26 @@
|
|
|
15
15
|
function defOf(schema) {
|
|
16
16
|
if (typeof schema !== 'object' || schema === null)
|
|
17
17
|
return null;
|
|
18
|
-
const def = schema.
|
|
18
|
+
const def = schema._zod?.def;
|
|
19
19
|
return typeof def === 'object' && def !== null ? def : null;
|
|
20
20
|
}
|
|
21
21
|
/** Wrapper types whose inner schema determines the coercion target. */
|
|
22
22
|
const WRAPPERS = new Set([
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
23
|
+
'optional',
|
|
24
|
+
'nullable',
|
|
25
|
+
'default',
|
|
26
|
+
'prefault',
|
|
27
|
+
'catch',
|
|
28
|
+
'readonly',
|
|
29
|
+
'nonoptional',
|
|
30
|
+
'pipe', // .transform() — the input side is what the client sends
|
|
30
31
|
]);
|
|
31
|
-
/** Unwraps optional/nullable/default/
|
|
32
|
+
/** Unwraps optional/nullable/default/pipe layers to the underlying def. */
|
|
32
33
|
function unwrap(schema) {
|
|
33
34
|
let def = defOf(schema);
|
|
34
35
|
let depth = 0;
|
|
35
|
-
while (def !== null && def.
|
|
36
|
-
def = defOf(def.innerType ?? def.
|
|
36
|
+
while (def !== null && def.type !== undefined && WRAPPERS.has(def.type) && depth < 16) {
|
|
37
|
+
def = defOf(def.innerType ?? def.in);
|
|
37
38
|
depth++;
|
|
38
39
|
}
|
|
39
40
|
return def;
|
|
@@ -42,21 +43,21 @@ function kindOf(fieldSchema) {
|
|
|
42
43
|
const def = unwrap(fieldSchema);
|
|
43
44
|
if (def === null)
|
|
44
45
|
return null;
|
|
45
|
-
switch (def.
|
|
46
|
-
case '
|
|
46
|
+
switch (def.type) {
|
|
47
|
+
case 'number':
|
|
47
48
|
return 'number';
|
|
48
|
-
case '
|
|
49
|
+
case 'boolean':
|
|
49
50
|
return 'boolean';
|
|
50
|
-
case '
|
|
51
|
+
case 'union': {
|
|
51
52
|
// Coerce only when every meaningful branch agrees on one primitive kind
|
|
52
53
|
// (e.g. z.union([z.number(), z.null()])). A string branch means the raw
|
|
53
54
|
// string is already acceptable — leave it alone.
|
|
54
55
|
const kinds = new Set();
|
|
55
56
|
for (const option of def.options ?? []) {
|
|
56
57
|
const inner = unwrap(option);
|
|
57
|
-
if (inner?.
|
|
58
|
+
if (inner?.type === 'null' || inner?.type === 'undefined')
|
|
58
59
|
continue;
|
|
59
|
-
kinds.add(inner?.
|
|
60
|
+
kinds.add(inner?.type === 'number' ? 'number' : inner?.type === 'boolean' ? 'boolean' : null);
|
|
60
61
|
}
|
|
61
62
|
if (kinds.size === 1) {
|
|
62
63
|
const only = kinds.values().next().value;
|
|
@@ -79,9 +80,9 @@ export function buildCoercionMaps(registry) {
|
|
|
79
80
|
if (cap.inputSchema === null)
|
|
80
81
|
continue;
|
|
81
82
|
const def = unwrap(cap.inputSchema);
|
|
82
|
-
if (def?.
|
|
83
|
+
if (def?.type !== 'object')
|
|
83
84
|
continue;
|
|
84
|
-
const shape =
|
|
85
|
+
const shape = def.shape ?? {};
|
|
85
86
|
const fields = new Map();
|
|
86
87
|
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
87
88
|
const kind = kindOf(fieldSchema);
|
package/dist/coercion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coercion.js","sourceRoot":"","sources":["../src/coercion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAkBH,SAAS,KAAK,CAAC,MAAe;IAC5B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/D,MAAM,GAAG,GAAI,
|
|
1
|
+
{"version":3,"file":"coercion.js","sourceRoot":"","sources":["../src/coercion.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export { compileRouter, generateRoutes } from './router.js';
|
|
|
7
7
|
export type { RouteDefinition, RouterMatch, Router, GenerateRoutesOptions, HttpOverride } from './router.js';
|
|
8
8
|
export { uploadedFile } from './multipart.js';
|
|
9
9
|
export type { UploadedFile, MultipartOptions } from './multipart.js';
|
|
10
|
+
export { generateOpenAPI } from './openapi.js';
|
|
11
|
+
export type { OpenAPIOptions, OpenAPIServer } from './openapi.js';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7G,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7G,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openapi.ts — generate an OpenAPI 3.1 document from a capability registry.
|
|
3
|
+
*
|
|
4
|
+
* Routes come from the same inference engine the REST transport uses at mount
|
|
5
|
+
* time (generateRoutes), so the spec always matches what the server actually
|
|
6
|
+
* serves — including urlCase and route overrides. Input schemas become path
|
|
7
|
+
* parameters, query parameters (for GET/DELETE), or a JSON request body
|
|
8
|
+
* (for POST/PATCH/PUT); output schemas become the `data` payload of the 200
|
|
9
|
+
* response, mirroring the transport's `{ "data": ... }` envelope.
|
|
10
|
+
*
|
|
11
|
+
* Use programmatically:
|
|
12
|
+
* import { generateOpenAPI } from '@capixjs/transport-rest';
|
|
13
|
+
* const spec = generateOpenAPI(registry, { title: 'My API', version: '1.0.0' });
|
|
14
|
+
*
|
|
15
|
+
* Or via the CLI:
|
|
16
|
+
* capix openapi --output openapi.json
|
|
17
|
+
*/
|
|
18
|
+
import type { CapabilityRegistry } from '@capixjs/core';
|
|
19
|
+
import type { HttpOverride } from './router.js';
|
|
20
|
+
export type OpenAPIServer = {
|
|
21
|
+
readonly url: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
};
|
|
24
|
+
export type OpenAPIOptions = {
|
|
25
|
+
/** info.title — default 'Capix API'. */
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
/** info.version — default '0.0.0'. */
|
|
28
|
+
readonly version?: string;
|
|
29
|
+
/** info.description. */
|
|
30
|
+
readonly description?: string;
|
|
31
|
+
/** servers array (e.g. [{ url: 'https://api.example.com' }]). */
|
|
32
|
+
readonly servers?: ReadonlyArray<OpenAPIServer>;
|
|
33
|
+
/** Case style for inferred URL segments — must match the restTransport option. */
|
|
34
|
+
readonly urlCase?: 'kebab' | 'camel' | 'snake';
|
|
35
|
+
/** Route overrides — must match the restTransport option for an accurate spec. */
|
|
36
|
+
readonly overrides?: Record<string, HttpOverride>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Generates an OpenAPI 3.1 document for every capability in the registry.
|
|
40
|
+
*
|
|
41
|
+
* Pass the same `urlCase` and `overrides` you give to `restTransport` so the
|
|
42
|
+
* generated paths match the running server.
|
|
43
|
+
*/
|
|
44
|
+
export declare function generateOpenAPI(registry: CapabilityRegistry, options?: OpenAPIOptions): Record<string, unknown>;
|
|
45
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,wBAAwB;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAChD,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACnD,CAAC;AAwDF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8HzB"}
|
package/dist/openapi.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openapi.ts — generate an OpenAPI 3.1 document from a capability registry.
|
|
3
|
+
*
|
|
4
|
+
* Routes come from the same inference engine the REST transport uses at mount
|
|
5
|
+
* time (generateRoutes), so the spec always matches what the server actually
|
|
6
|
+
* serves — including urlCase and route overrides. Input schemas become path
|
|
7
|
+
* parameters, query parameters (for GET/DELETE), or a JSON request body
|
|
8
|
+
* (for POST/PATCH/PUT); output schemas become the `data` payload of the 200
|
|
9
|
+
* response, mirroring the transport's `{ "data": ... }` envelope.
|
|
10
|
+
*
|
|
11
|
+
* Use programmatically:
|
|
12
|
+
* import { generateOpenAPI } from '@capixjs/transport-rest';
|
|
13
|
+
* const spec = generateOpenAPI(registry, { title: 'My API', version: '1.0.0' });
|
|
14
|
+
*
|
|
15
|
+
* Or via the CLI:
|
|
16
|
+
* capix openapi --output openapi.json
|
|
17
|
+
*/
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
import { generateRoutes } from './router.js';
|
|
20
|
+
const NO_BODY_METHODS = new Set(['GET', 'HEAD', 'DELETE']);
|
|
21
|
+
const ERROR_RESPONSE_SCHEMA = {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
error: { type: 'string', description: 'Machine-readable error code (e.g. NotFound)' },
|
|
25
|
+
message: { type: 'string', description: 'Human-readable error message' },
|
|
26
|
+
meta: { type: 'object', additionalProperties: true, description: 'Optional error details' },
|
|
27
|
+
},
|
|
28
|
+
required: ['error', 'message'],
|
|
29
|
+
};
|
|
30
|
+
function errorRef(description) {
|
|
31
|
+
return {
|
|
32
|
+
description,
|
|
33
|
+
content: {
|
|
34
|
+
'application/json': {
|
|
35
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Converts a Zod schema to JSON Schema; null when conversion fails.
|
|
42
|
+
* Targets draft 2020-12 — the dialect OpenAPI 3.1 uses natively.
|
|
43
|
+
* `io` picks the schema side: 'input' for request schemas (fields with
|
|
44
|
+
* defaults become optional), 'output' for response schemas.
|
|
45
|
+
*/
|
|
46
|
+
function toJsonSchema(schema, io) {
|
|
47
|
+
try {
|
|
48
|
+
const js = z.toJSONSchema(schema, {
|
|
49
|
+
io,
|
|
50
|
+
reused: 'inline',
|
|
51
|
+
unrepresentable: 'any',
|
|
52
|
+
});
|
|
53
|
+
delete js['$schema'];
|
|
54
|
+
return js;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function pathParamNames(routePath) {
|
|
61
|
+
const names = [];
|
|
62
|
+
for (const seg of routePath.split('/')) {
|
|
63
|
+
if (seg.startsWith(':'))
|
|
64
|
+
names.push(seg.slice(1));
|
|
65
|
+
}
|
|
66
|
+
return names;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generates an OpenAPI 3.1 document for every capability in the registry.
|
|
70
|
+
*
|
|
71
|
+
* Pass the same `urlCase` and `overrides` you give to `restTransport` so the
|
|
72
|
+
* generated paths match the running server.
|
|
73
|
+
*/
|
|
74
|
+
export function generateOpenAPI(registry, options = {}) {
|
|
75
|
+
const routes = generateRoutes(registry, {
|
|
76
|
+
...(options.urlCase !== undefined ? { urlCase: options.urlCase } : {}),
|
|
77
|
+
...(options.overrides !== undefined ? { overrides: options.overrides } : {}),
|
|
78
|
+
});
|
|
79
|
+
const paths = {};
|
|
80
|
+
const tags = new Set();
|
|
81
|
+
for (const route of routes) {
|
|
82
|
+
const cap = registry.get(route.capability);
|
|
83
|
+
if (cap === undefined)
|
|
84
|
+
continue;
|
|
85
|
+
const openapiPath = route.path.replace(/:([^/]+)/g, '{$1}');
|
|
86
|
+
const params = pathParamNames(route.path);
|
|
87
|
+
const paramSet = new Set(params);
|
|
88
|
+
const inputJs = cap.inputSchema !== null ? toJsonSchema(cap.inputSchema, 'input') : null;
|
|
89
|
+
const properties = (inputJs?.['properties'] ?? {});
|
|
90
|
+
const requiredFields = new Set((inputJs?.['required'] ?? []));
|
|
91
|
+
// Object schemas split into parameters/body; non-object schemas (z.record,
|
|
92
|
+
// z.any) can't be decomposed — they become the whole request body.
|
|
93
|
+
const isObjectSchema = inputJs !== null && 'properties' in inputJs;
|
|
94
|
+
const parameters = [];
|
|
95
|
+
for (const name of params) {
|
|
96
|
+
parameters.push({
|
|
97
|
+
name,
|
|
98
|
+
in: 'path',
|
|
99
|
+
required: true,
|
|
100
|
+
schema: properties[name] ?? { type: 'string' },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
let requestBody = null;
|
|
104
|
+
if (NO_BODY_METHODS.has(route.method)) {
|
|
105
|
+
// Remaining schema fields are query parameters
|
|
106
|
+
for (const [name, schema] of Object.entries(properties)) {
|
|
107
|
+
if (paramSet.has(name))
|
|
108
|
+
continue;
|
|
109
|
+
parameters.push({
|
|
110
|
+
name,
|
|
111
|
+
in: 'query',
|
|
112
|
+
required: requiredFields.has(name),
|
|
113
|
+
schema,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else if (isObjectSchema) {
|
|
118
|
+
const bodyProps = {};
|
|
119
|
+
const bodyRequired = [];
|
|
120
|
+
for (const [name, schema] of Object.entries(properties)) {
|
|
121
|
+
if (paramSet.has(name))
|
|
122
|
+
continue;
|
|
123
|
+
bodyProps[name] = schema;
|
|
124
|
+
if (requiredFields.has(name))
|
|
125
|
+
bodyRequired.push(name);
|
|
126
|
+
}
|
|
127
|
+
if (Object.keys(bodyProps).length > 0) {
|
|
128
|
+
requestBody = {
|
|
129
|
+
required: bodyRequired.length > 0,
|
|
130
|
+
content: {
|
|
131
|
+
'application/json': {
|
|
132
|
+
schema: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
properties: bodyProps,
|
|
135
|
+
...(bodyRequired.length > 0 ? { required: bodyRequired } : {}),
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if (inputJs !== null) {
|
|
143
|
+
requestBody = {
|
|
144
|
+
required: true,
|
|
145
|
+
content: { 'application/json': { schema: inputJs } },
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const outputJs = cap.outputSchema !== null ? toJsonSchema(cap.outputSchema, 'output') : null;
|
|
149
|
+
const responses = {
|
|
150
|
+
'200': {
|
|
151
|
+
description: 'Success',
|
|
152
|
+
content: {
|
|
153
|
+
'application/json': {
|
|
154
|
+
schema: {
|
|
155
|
+
type: 'object',
|
|
156
|
+
properties: { data: outputJs ?? {} },
|
|
157
|
+
required: ['data'],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
...(cap.inputSchema !== null ? { '400': errorRef('Validation error') } : {}),
|
|
163
|
+
default: errorRef('Error'),
|
|
164
|
+
};
|
|
165
|
+
const segments = route.capability.split('.');
|
|
166
|
+
const group = segments.length > 1 ? segments[0] : null;
|
|
167
|
+
if (group !== null)
|
|
168
|
+
tags.add(group);
|
|
169
|
+
const operation = {
|
|
170
|
+
operationId: route.capability.replaceAll('.', '_'),
|
|
171
|
+
summary: route.capability,
|
|
172
|
+
...(group !== null ? { tags: [group] } : {}),
|
|
173
|
+
...(parameters.length > 0 ? { parameters } : {}),
|
|
174
|
+
...(requestBody !== null ? { requestBody } : {}),
|
|
175
|
+
responses,
|
|
176
|
+
};
|
|
177
|
+
if (!(openapiPath in paths))
|
|
178
|
+
paths[openapiPath] = {};
|
|
179
|
+
paths[openapiPath][route.method.toLowerCase()] = operation;
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
openapi: '3.1.0',
|
|
183
|
+
info: {
|
|
184
|
+
title: options.title ?? 'Capix API',
|
|
185
|
+
version: options.version ?? '0.0.0',
|
|
186
|
+
...(options.description !== undefined ? { description: options.description } : {}),
|
|
187
|
+
},
|
|
188
|
+
...(options.servers !== undefined && options.servers.length > 0
|
|
189
|
+
? { servers: options.servers }
|
|
190
|
+
: {}),
|
|
191
|
+
paths,
|
|
192
|
+
components: { schemas: { ErrorResponse: ERROR_RESPONSE_SCHEMA } },
|
|
193
|
+
...(tags.size > 0 ? { tags: [...tags].sort().map((name) => ({ name })) } : {}),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA0B7C,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE3D,MAAM,qBAAqB,GAAe;IACxC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE;QACvF,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;QACxE,IAAI,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,WAAW,EAAE,wBAAwB,EAAE;KAC/F;IACD,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;CAC/B,CAAC;AAEF,SAAS,QAAQ,CAAC,WAAmB;IACnC,OAAO;QACL,WAAW;QACX,OAAO,EAAE;YACP,kBAAkB,EAAE;gBAClB,MAAM,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE;aACvD;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,MAAe,EAAE,EAAsB;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC,MAAmB,EAAE;YAC7C,EAAE;YACF,MAAM,EAAE,QAAQ;YAChB,eAAe,EAAE,KAAK;SACvB,CAAe,CAAC;QACjB,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAA4B,EAC5B,UAA0B,EAAE;IAE5B,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE;QACtC,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAC,CAAC;IAEH,MAAM,KAAK,GAA8C,EAAE,CAAC;IAC5D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAEhC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzF,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,CAA+B,CAAC;QACjF,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,CAAa,CAAC,CAAC;QAC1E,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,cAAc,GAAG,OAAO,KAAK,IAAI,IAAI,YAAY,IAAI,OAAO,CAAC;QAEnE,MAAM,UAAU,GAA8B,EAAE,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI;gBACJ,EAAE,EAAE,MAAM;gBACV,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC/C,CAAC,CAAC;QACL,CAAC;QAED,IAAI,WAAW,GAAmC,IAAI,CAAC;QAEvD,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,+CAA+C;YAC/C,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxD,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACjC,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI;oBACJ,EAAE,EAAE,OAAO;oBACX,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;oBAClC,MAAM;iBACP,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,MAAM,SAAS,GAA+B,EAAE,CAAC;YACjD,MAAM,YAAY,GAAa,EAAE,CAAC;YAClC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxD,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACjC,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;gBACzB,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtC,WAAW,GAAG;oBACZ,QAAQ,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;oBACjC,OAAO,EAAE;wBACP,kBAAkB,EAAE;4BAClB,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE,SAAS;gCACrB,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BAC/D;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YAC5B,WAAW,GAAG;gBACZ,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;aACrD,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE7F,MAAM,SAAS,GAA4B;YACzC,KAAK,EAAE;gBACL,WAAW,EAAE,SAAS;gBACtB,OAAO,EAAE;oBACP,kBAAkB,EAAE;wBAClB,MAAM,EAAE;4BACN,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,EAAE;4BACpC,QAAQ,EAAE,CAAC,MAAM,CAAC;yBACnB;qBACF;iBACF;aACF;YACD,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;SAC3B,CAAC;QAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACxD,IAAI,KAAK,KAAK,IAAI;YAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEpC,MAAM,SAAS,GAAc;YAC3B,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;YAClD,OAAO,EAAE,KAAK,CAAC,UAAU;YACzB,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,SAAS;SACV,CAAC;QAEF,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC;YAAE,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QACrD,KAAK,CAAC,WAAW,CAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,SAAS,CAAC;IAC9D,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,WAAW;YACnC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO;YACnC,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnF;QACD,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAC7D,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;YAC9B,CAAC,CAAC,EAAE,CAAC;QACP,KAAK;QACL,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,qBAAqB,EAAE,EAAE;QACjE,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/E,CAAC;AACJ,CAAC"}
|
package/dist/serializer.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { DEFAULT as defaultSerializer };
|
|
|
13
13
|
/**
|
|
14
14
|
* Builds per-capability serializers from compiled output schemas.
|
|
15
15
|
* Falls back to JSON.stringify for capabilities without an outputSchema or
|
|
16
|
-
* if
|
|
16
|
+
* if the schema cannot be converted to JSON Schema (e.g. contains z.date()).
|
|
17
17
|
*/
|
|
18
18
|
export declare function buildSerializers(registry: CapabilityRegistry): Map<string, ResponseSerializer>;
|
|
19
19
|
//# sourceMappingURL=serializer.d.ts.map
|
package/dist/serializer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,iEAAiE;AACjE,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;AAE3D,QAAA,MAAM,OAAO,EAAE,kBAAsE,CAAC;AAEtF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,iEAAiE;AACjE,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;AAE3D,QAAA,MAAM,OAAO,EAAE,kBAAsE,CAAC;AAEtF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAyB9F"}
|
package/dist/serializer.js
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
* per-request setup cost.
|
|
7
7
|
*/
|
|
8
8
|
import fastJsonStringify from 'fast-json-stringify';
|
|
9
|
-
import {
|
|
9
|
+
import { z } from 'zod';
|
|
10
10
|
const DEFAULT = (data) => '{"data":' + JSON.stringify(data) + '}';
|
|
11
11
|
export { DEFAULT as defaultSerializer };
|
|
12
12
|
/**
|
|
13
13
|
* Builds per-capability serializers from compiled output schemas.
|
|
14
14
|
* Falls back to JSON.stringify for capabilities without an outputSchema or
|
|
15
|
-
* if
|
|
15
|
+
* if the schema cannot be converted to JSON Schema (e.g. contains z.date()).
|
|
16
16
|
*/
|
|
17
17
|
export function buildSerializers(registry) {
|
|
18
18
|
const map = new Map();
|
|
@@ -20,9 +20,10 @@ export function buildSerializers(registry) {
|
|
|
20
20
|
if (cap.outputSchema === null)
|
|
21
21
|
continue;
|
|
22
22
|
try {
|
|
23
|
-
const jsonSchema =
|
|
24
|
-
target: '
|
|
25
|
-
|
|
23
|
+
const jsonSchema = z.toJSONSchema(cap.outputSchema, {
|
|
24
|
+
target: 'draft-7',
|
|
25
|
+
io: 'output',
|
|
26
|
+
reused: 'inline',
|
|
26
27
|
});
|
|
27
28
|
// Remove the $schema meta field — fjs doesn't need it
|
|
28
29
|
if (typeof jsonSchema === 'object' && jsonSchema !== null) {
|
package/dist/serializer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,MAAM,OAAO,GAAuB,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAEtF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAA4B;IAC3D,MAAM,GAAG,GAAG,IAAI,GAAG,EAA8B,CAAC;IAElD,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;QACtC,IAAI,GAAG,CAAC,YAAY,KAAK,IAAI;YAAE,SAAS;QAExC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,YAAyB,EAAE;gBAC/D,MAAM,EAAE,SAAS;gBACjB,EAAE,EAAE,QAAQ;gBACZ,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;YACH,sDAAsD;YACtD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC1D,OAAQ,UAAsC,CAAC,SAAS,CAAC,CAAC;YAC5D,CAAC;YAED,MAAM,aAAa,GAAG,iBAAiB,CAAC,UAAqD,CAAC,CAAC;YAC/F,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,mGAAmG;QACrG,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capixjs/transport-rest",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.14",
|
|
4
4
|
"description": "Capix HTTP/REST transport",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,8 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"busboy": "^1.6.0",
|
|
35
35
|
"fast-json-stringify": "^6.4.0",
|
|
36
|
-
"zod": "^
|
|
37
|
-
"zod-to-json-schema": "^3.25.2"
|
|
36
|
+
"zod": "^4.0.0"
|
|
38
37
|
},
|
|
39
38
|
"peerDependencies": {
|
|
40
39
|
"@capixjs/core": ">=0.1.0-0"
|
|
@@ -46,7 +45,7 @@
|
|
|
46
45
|
"form-data": "^4.0.5",
|
|
47
46
|
"typescript": "^5.5.0",
|
|
48
47
|
"vitest": "^1.6.0",
|
|
49
|
-
"@capixjs/core": "0.1.0-alpha.
|
|
48
|
+
"@capixjs/core": "0.1.0-alpha.14"
|
|
50
49
|
},
|
|
51
50
|
"scripts": {
|
|
52
51
|
"build": "tsc",
|