vovk 3.0.0-draft.21 → 3.0.0-draft.211

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.
Files changed (169) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -96
  3. package/bin/index.mjs +8 -0
  4. package/{HttpException.d.ts → cjs/HttpException.d.ts} +2 -2
  5. package/{HttpException.js → cjs/HttpException.js} +3 -3
  6. package/cjs/JSONLinesResponse.d.ts +14 -0
  7. package/{StreamJSONResponse.js → cjs/JSONLinesResponse.js} +15 -10
  8. package/{Segment.d.ts → cjs/VovkApp.d.ts} +11 -10
  9. package/cjs/VovkApp.js +189 -0
  10. package/cjs/client/createRPC.d.ts +3 -0
  11. package/cjs/client/createRPC.js +87 -0
  12. package/{client → cjs/client}/defaultHandler.d.ts +1 -1
  13. package/cjs/client/defaultHandler.js +22 -0
  14. package/cjs/client/defaultStreamHandler.d.ts +4 -0
  15. package/{client → cjs/client}/defaultStreamHandler.js +11 -12
  16. package/cjs/client/fetcher.d.ts +13 -0
  17. package/cjs/client/fetcher.js +90 -0
  18. package/cjs/client/index.d.ts +3 -0
  19. package/cjs/client/index.js +8 -0
  20. package/cjs/client/types.d.ts +111 -0
  21. package/{createSegment.d.ts → cjs/createVovkApp.d.ts} +11 -10
  22. package/cjs/createVovkApp.js +132 -0
  23. package/cjs/index.d.ts +65 -0
  24. package/cjs/index.js +37 -0
  25. package/cjs/openapi/error.d.ts +2 -0
  26. package/cjs/openapi/error.js +100 -0
  27. package/cjs/openapi/generateFnName.d.ts +23 -0
  28. package/cjs/openapi/generateFnName.js +81 -0
  29. package/cjs/openapi/index.d.ts +12 -0
  30. package/cjs/openapi/index.js +21 -0
  31. package/cjs/openapi/openAPIToVovkSchema.d.ts +2 -0
  32. package/cjs/openapi/openAPIToVovkSchema.js +197 -0
  33. package/cjs/openapi/vovkSchemaToOpenAPI.d.ts +9 -0
  34. package/cjs/openapi/vovkSchemaToOpenAPI.js +237 -0
  35. package/cjs/types.d.ts +364 -0
  36. package/cjs/types.js +74 -0
  37. package/cjs/utils/camelCase.d.ts +6 -0
  38. package/cjs/utils/camelCase.js +37 -0
  39. package/cjs/utils/createCodeExamples.d.ts +19 -0
  40. package/cjs/utils/createCodeExamples.js +114 -0
  41. package/cjs/utils/createDecorator.d.ts +6 -0
  42. package/{createDecorator.js → cjs/utils/createDecorator.js} +24 -16
  43. package/cjs/utils/createLLMFunctions.d.ts +20 -0
  44. package/cjs/utils/createLLMFunctions.js +100 -0
  45. package/cjs/utils/generateStaticAPI.d.ts +4 -0
  46. package/cjs/utils/generateStaticAPI.js +30 -0
  47. package/cjs/utils/getSchema.d.ts +21 -0
  48. package/cjs/utils/getSchema.js +43 -0
  49. package/cjs/utils/multitenant.d.ts +24 -0
  50. package/cjs/utils/multitenant.js +170 -0
  51. package/cjs/utils/parseQuery.d.ts +25 -0
  52. package/cjs/utils/parseQuery.js +156 -0
  53. package/cjs/utils/reqForm.d.ts +2 -0
  54. package/cjs/utils/reqForm.js +33 -0
  55. package/{utils → cjs/utils}/reqMeta.d.ts +1 -2
  56. package/cjs/utils/reqQuery.d.ts +2 -0
  57. package/cjs/utils/reqQuery.js +10 -0
  58. package/cjs/utils/serializeQuery.d.ts +13 -0
  59. package/cjs/utils/serializeQuery.js +65 -0
  60. package/cjs/utils/setHandlerSchema.d.ts +4 -0
  61. package/cjs/utils/setHandlerSchema.js +15 -0
  62. package/cjs/utils/withStandard.d.ts +51 -0
  63. package/cjs/utils/withStandard.js +30 -0
  64. package/cjs/utils/withValidationLibrary.d.ts +49 -0
  65. package/cjs/utils/withValidationLibrary.js +123 -0
  66. package/mjs/HttpException.d.ts +7 -0
  67. package/mjs/HttpException.js +15 -0
  68. package/mjs/JSONLinesResponse.d.ts +14 -0
  69. package/mjs/JSONLinesResponse.js +59 -0
  70. package/mjs/VovkApp.d.ts +29 -0
  71. package/mjs/VovkApp.js +189 -0
  72. package/mjs/client/createRPC.d.ts +3 -0
  73. package/mjs/client/createRPC.js +87 -0
  74. package/mjs/client/defaultHandler.d.ts +2 -0
  75. package/mjs/client/defaultHandler.js +22 -0
  76. package/mjs/client/defaultStreamHandler.d.ts +4 -0
  77. package/mjs/client/defaultStreamHandler.js +81 -0
  78. package/mjs/client/fetcher.d.ts +13 -0
  79. package/mjs/client/fetcher.js +90 -0
  80. package/mjs/client/index.d.ts +3 -0
  81. package/mjs/client/index.js +8 -0
  82. package/mjs/client/types.d.ts +111 -0
  83. package/mjs/createVovkApp.d.ts +63 -0
  84. package/mjs/createVovkApp.js +132 -0
  85. package/mjs/index.d.ts +65 -0
  86. package/mjs/index.js +37 -0
  87. package/mjs/openapi/error.d.ts +2 -0
  88. package/mjs/openapi/error.js +100 -0
  89. package/mjs/openapi/generateFnName.d.ts +23 -0
  90. package/mjs/openapi/generateFnName.js +81 -0
  91. package/mjs/openapi/index.d.ts +12 -0
  92. package/mjs/openapi/index.js +21 -0
  93. package/mjs/openapi/openAPIToVovkSchema.d.ts +2 -0
  94. package/mjs/openapi/openAPIToVovkSchema.js +197 -0
  95. package/mjs/openapi/vovkSchemaToOpenAPI.d.ts +9 -0
  96. package/mjs/openapi/vovkSchemaToOpenAPI.js +237 -0
  97. package/mjs/types.d.ts +364 -0
  98. package/mjs/types.js +74 -0
  99. package/mjs/utils/camelCase.d.ts +6 -0
  100. package/mjs/utils/camelCase.js +37 -0
  101. package/mjs/utils/createCodeExamples.d.ts +19 -0
  102. package/mjs/utils/createCodeExamples.js +114 -0
  103. package/mjs/utils/createDecorator.d.ts +6 -0
  104. package/mjs/utils/createDecorator.js +46 -0
  105. package/mjs/utils/createLLMFunctions.d.ts +20 -0
  106. package/mjs/utils/createLLMFunctions.js +100 -0
  107. package/mjs/utils/generateStaticAPI.d.ts +4 -0
  108. package/mjs/utils/generateStaticAPI.js +30 -0
  109. package/mjs/utils/getSchema.d.ts +21 -0
  110. package/mjs/utils/getSchema.js +43 -0
  111. package/mjs/utils/multitenant.d.ts +24 -0
  112. package/mjs/utils/multitenant.js +170 -0
  113. package/mjs/utils/parseQuery.d.ts +25 -0
  114. package/mjs/utils/parseQuery.js +156 -0
  115. package/mjs/utils/reqForm.d.ts +2 -0
  116. package/mjs/utils/reqForm.js +33 -0
  117. package/mjs/utils/reqMeta.d.ts +2 -0
  118. package/mjs/utils/reqMeta.js +13 -0
  119. package/mjs/utils/reqQuery.d.ts +2 -0
  120. package/mjs/utils/reqQuery.js +10 -0
  121. package/mjs/utils/serializeQuery.d.ts +13 -0
  122. package/mjs/utils/serializeQuery.js +65 -0
  123. package/mjs/utils/setHandlerSchema.d.ts +4 -0
  124. package/mjs/utils/setHandlerSchema.js +15 -0
  125. package/mjs/utils/shim.d.ts +1 -0
  126. package/mjs/utils/shim.js +18 -0
  127. package/mjs/utils/withStandard.d.ts +51 -0
  128. package/mjs/utils/withStandard.js +30 -0
  129. package/mjs/utils/withValidationLibrary.d.ts +49 -0
  130. package/mjs/utils/withValidationLibrary.js +123 -0
  131. package/package.json +30 -5
  132. package/.npmignore +0 -2
  133. package/Segment.js +0 -182
  134. package/StreamJSONResponse.d.ts +0 -17
  135. package/client/clientizeController.d.ts +0 -4
  136. package/client/clientizeController.js +0 -92
  137. package/client/defaultFetcher.d.ts +0 -4
  138. package/client/defaultFetcher.js +0 -49
  139. package/client/defaultHandler.js +0 -21
  140. package/client/defaultStreamHandler.d.ts +0 -4
  141. package/client/index.d.ts +0 -4
  142. package/client/index.js +0 -5
  143. package/client/types.d.ts +0 -100
  144. package/createDecorator.d.ts +0 -4
  145. package/createSegment.js +0 -118
  146. package/generateStaticAPI.d.ts +0 -4
  147. package/generateStaticAPI.js +0 -18
  148. package/index.d.ts +0 -60
  149. package/index.js +0 -20
  150. package/types.d.ts +0 -155
  151. package/types.js +0 -65
  152. package/utils/getSchema.d.ts +0 -8
  153. package/utils/getSchema.js +0 -38
  154. package/utils/reqQuery.d.ts +0 -3
  155. package/utils/reqQuery.js +0 -25
  156. package/utils/setClientValidatorsForHandler.d.ts +0 -5
  157. package/utils/setClientValidatorsForHandler.js +0 -28
  158. package/worker/index.d.ts +0 -3
  159. package/worker/index.js +0 -7
  160. package/worker/promisifyWorker.d.ts +0 -2
  161. package/worker/promisifyWorker.js +0 -141
  162. package/worker/types.d.ts +0 -31
  163. package/worker/worker.d.ts +0 -1
  164. package/worker/worker.js +0 -43
  165. /package/{client → cjs/client}/types.js +0 -0
  166. /package/{utils → cjs/utils}/reqMeta.js +0 -0
  167. /package/{utils → cjs/utils}/shim.d.ts +0 -0
  168. /package/{utils → cjs/utils}/shim.js +0 -0
  169. /package/{worker → mjs/client}/types.js +0 -0
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openAPIToVovkSchema = openAPIToVovkSchema;
4
+ const types_1 = require("../types");
5
+ const generateFnName_1 = require("./generateFnName");
6
+ const camelCase_1 = require("../utils/camelCase");
7
+ // fast clone JSON object while ignoring Date, RegExp, and Function types
8
+ function cloneJSON(obj) {
9
+ if (obj === null || typeof obj !== 'object')
10
+ return obj;
11
+ if (Array.isArray(obj))
12
+ return obj.map(cloneJSON);
13
+ const result = {};
14
+ for (const [key, value] of Object.entries(obj)) {
15
+ if (value instanceof Date || value instanceof RegExp || typeof value === 'function')
16
+ continue;
17
+ result[key] = cloneJSON(value);
18
+ }
19
+ return result;
20
+ }
21
+ function applyComponents(schema, components) {
22
+ if (!components || !Object.keys(components).length)
23
+ return schema;
24
+ // Create a deep copy of the schema
25
+ const result = cloneJSON(schema);
26
+ // Initialize $defs if it doesn't exist
27
+ result.$defs = result.$defs || {};
28
+ // Set to track components we've added to $defs
29
+ const addedComponents = new Set();
30
+ // Process a schema object and replace $refs
31
+ function processSchema(obj) {
32
+ if (!obj || typeof obj !== 'object')
33
+ return obj;
34
+ // Create a new object/array to avoid modifying the input
35
+ const newObj = Array.isArray(obj) ? [...obj] : { ...obj };
36
+ // Check for $ref
37
+ if (newObj.$ref && typeof newObj.$ref === 'string' && newObj.$ref.startsWith('#/components/schemas/')) {
38
+ const componentName = newObj.$ref.replace('#/components/schemas/', '');
39
+ newObj.$ref = `#/$defs/${componentName}`;
40
+ // Add the component to $defs if not already added
41
+ if (!addedComponents.has(componentName) && components[componentName]) {
42
+ addedComponents.add(componentName);
43
+ // TODO: IMPORTANT! Deep copy to avoid mutation issues
44
+ result.$defs[componentName] = processSchema(cloneJSON(components[componentName]));
45
+ }
46
+ }
47
+ // Process properties/items recursively
48
+ if (Array.isArray(newObj)) {
49
+ for (let i = 0; i < newObj.length; i++) {
50
+ newObj[i] = processSchema(newObj[i]);
51
+ }
52
+ }
53
+ else {
54
+ for (const key in newObj) {
55
+ if (Object.prototype.hasOwnProperty.call(newObj, key)) {
56
+ newObj[key] = processSchema(newObj[key]);
57
+ }
58
+ }
59
+ }
60
+ return newObj;
61
+ }
62
+ // Process the main schema
63
+ return processSchema(result);
64
+ }
65
+ const getNamesNestJS = (operationObject) => {
66
+ const operationId = operationObject.operationId;
67
+ if (!operationId) {
68
+ throw new Error('Operation ID is required for NestJS module name generation');
69
+ }
70
+ const controllerHandlerMatch = operationId?.match(/^([A-Z][a-zA-Z0-9]*)_([a-zA-Z0-9_]+)/);
71
+ if (!controllerHandlerMatch) {
72
+ throw new Error(`Invalid operationId format for NestJS: ${operationId}`);
73
+ }
74
+ return controllerHandlerMatch.slice(1, 3);
75
+ };
76
+ const normalizeGetModuleName = (getModuleName) => {
77
+ if (getModuleName === 'nestjs-operation-id') {
78
+ getModuleName = (operationObject) => getNamesNestJS(operationObject)[0];
79
+ }
80
+ else if (typeof getModuleName === 'string') {
81
+ const moduleName = getModuleName;
82
+ getModuleName = () => moduleName;
83
+ }
84
+ else if (typeof getModuleName !== 'function') {
85
+ throw new Error('getModuleName must be a function or one of the predefined strings');
86
+ }
87
+ return getModuleName;
88
+ };
89
+ const normalizeGetMethodName = (getMethodName) => {
90
+ if (getMethodName === 'nestjs-operation-id') {
91
+ getMethodName = (operationObject) => getNamesNestJS(operationObject)[1];
92
+ }
93
+ else if (getMethodName === 'camel-case-operation-id') {
94
+ getMethodName = ({ operationObject }) => {
95
+ const operationId = operationObject.operationId;
96
+ if (!operationId) {
97
+ throw new Error('Operation ID is required for camel-case method name generation');
98
+ }
99
+ return (0, camelCase_1.camelCase)(operationId);
100
+ };
101
+ }
102
+ else if (getMethodName === 'auto') {
103
+ getMethodName = ({ operationObject, method, path }) => {
104
+ const operationId = operationObject.operationId;
105
+ const isSnakeCase = operationId && /^[a-z][a-z0-9_]+$/.test(operationId);
106
+ return isSnakeCase ? (0, camelCase_1.camelCase)(operationId) : (0, generateFnName_1.generateFnName)(method, path);
107
+ };
108
+ }
109
+ else if (typeof getMethodName !== 'function') {
110
+ throw new Error('getMethodName must be a function or one of the predefined strings');
111
+ }
112
+ return getMethodName;
113
+ };
114
+ function openAPIToVovkSchema({ apiRoot, source: { object: openAPIObject }, getModuleName = 'api', getMethodName = 'auto', }) {
115
+ const forceApiRoot = apiRoot ?? openAPIObject.servers?.[0]?.url;
116
+ if (!forceApiRoot) {
117
+ throw new Error('API root URL is required in OpenAPI configuration');
118
+ }
119
+ const schema = {
120
+ $schema: types_1.VovkSchemaIdEnum.SCHEMA,
121
+ segments: {
122
+ '': {
123
+ $schema: types_1.VovkSchemaIdEnum.SEGMENT,
124
+ emitSchema: true,
125
+ segmentName: '',
126
+ forceApiRoot,
127
+ controllers: {},
128
+ },
129
+ },
130
+ meta: {
131
+ $schema: types_1.VovkSchemaIdEnum.META,
132
+ config: {
133
+ $schema: types_1.VovkSchemaIdEnum.CONFIG,
134
+ },
135
+ openapi: openAPIObject,
136
+ },
137
+ };
138
+ const segment = schema.segments[''];
139
+ getModuleName = normalizeGetModuleName(getModuleName);
140
+ getMethodName = normalizeGetMethodName(getMethodName);
141
+ return Object.entries(openAPIObject.paths ?? {}).reduce((acc, [path, operations]) => {
142
+ Object.entries(operations ?? {}).forEach(([method, operation]) => {
143
+ const rpcModuleName = getModuleName({
144
+ method: method.toUpperCase(),
145
+ path,
146
+ openAPIObject,
147
+ operationObject: operation,
148
+ });
149
+ const handlerName = getMethodName({
150
+ method: method.toUpperCase(),
151
+ path,
152
+ openAPIObject,
153
+ operationObject: operation,
154
+ });
155
+ segment.controllers[rpcModuleName] ??= {
156
+ rpcModuleName,
157
+ handlers: {},
158
+ };
159
+ // TODO: how to utilize ReferenceObject?
160
+ const queryProperties = operation.parameters?.filter((p) => p.in === 'query') ?? null;
161
+ const pathProperties = operation.parameters?.filter((p) => p.in === 'path') ?? null;
162
+ const query = queryProperties?.length
163
+ ? {
164
+ type: 'object',
165
+ properties: Object.fromEntries(queryProperties.map((p) => [p.name, p.schema])),
166
+ required: queryProperties.filter((p) => p.required).map((p) => p.name),
167
+ }
168
+ : null;
169
+ const params = pathProperties?.length
170
+ ? {
171
+ type: 'object',
172
+ properties: Object.fromEntries(pathProperties.map((p) => [p.name, p.schema])),
173
+ required: pathProperties.filter((p) => p.required).map((p) => p.name),
174
+ }
175
+ : null;
176
+ // TODO: how to utilize ReferenceObject?
177
+ const body = operation.requestBody?.content['application/json']?.schema ?? null;
178
+ const output = operation.responses?.['200']?.content?.['application/json']?.schema ??
179
+ operation.responses?.['201']?.content?.['application/json']?.schema ??
180
+ null;
181
+ // TODO: "iteration" validation
182
+ // TODO: FormData
183
+ segment.controllers[rpcModuleName].handlers[handlerName] = {
184
+ httpMethod: method.toUpperCase(),
185
+ path,
186
+ openapi: operation,
187
+ validation: {
188
+ ...(query && { query: applyComponents(query, openAPIObject.components?.schemas) }),
189
+ ...(params && { params: applyComponents(params, openAPIObject.components?.schemas) }),
190
+ ...(body && { body: applyComponents(body, openAPIObject.components?.schemas) }),
191
+ ...(output && { output: applyComponents(output, openAPIObject.components?.schemas) }),
192
+ },
193
+ };
194
+ });
195
+ return acc;
196
+ }, schema);
197
+ }
@@ -0,0 +1,9 @@
1
+ import type { OpenAPIObject } from 'openapi3-ts/oas31';
2
+ import { type CodeSamplePackageJson } from '../utils/createCodeExamples';
3
+ import { type VovkSchema } from '../types';
4
+ export declare function vovkSchemaToOpenAPI({ rootEntry, schema: fullSchema, openAPIObject, package: packageJson, }: {
5
+ rootEntry: string;
6
+ schema: VovkSchema;
7
+ openAPIObject?: Partial<OpenAPIObject>;
8
+ package?: CodeSamplePackageJson;
9
+ }): OpenAPIObject;
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.vovkSchemaToOpenAPI = vovkSchemaToOpenAPI;
4
+ const json_schema_sampler_1 = require("@stoplight/json-schema-sampler");
5
+ const createCodeExamples_1 = require("../utils/createCodeExamples");
6
+ const types_1 = require("../types");
7
+ function extractComponents(schema) {
8
+ if (!schema)
9
+ return [undefined, {}];
10
+ const components = {};
11
+ // Function to collect components and replace $refs recursively
12
+ const process = (obj, path = []) => {
13
+ if (!obj || typeof obj !== 'object')
14
+ return obj;
15
+ // Handle arrays
16
+ if (Array.isArray(obj)) {
17
+ return obj.map((item) => process(item, path));
18
+ }
19
+ // Create a copy to modify
20
+ const result = {};
21
+ Object.entries({ ...obj.definitions, ...obj.$defs }).forEach(([key, value]) => {
22
+ components[key] = process(value, [...path, key]);
23
+ });
24
+ // Process all properties
25
+ for (const [key, value] of Object.entries(obj ?? {})) {
26
+ // Skip already processed special properties
27
+ if (key === '$defs' || key === 'definitions')
28
+ continue;
29
+ if (key === '$ref' && typeof value === 'string') {
30
+ // Extract the component name from the reference
31
+ const refParts = value.split('/');
32
+ const refName = refParts[refParts.length - 1];
33
+ // Replace with component reference
34
+ result[key] = `#/components/schemas/${refName}`;
35
+ }
36
+ else {
37
+ // Recursively process other properties
38
+ result[key] = process(value, [...path, key]);
39
+ }
40
+ }
41
+ return result;
42
+ };
43
+ const processedSchema = process(schema);
44
+ return [processedSchema, components];
45
+ }
46
+ function vovkSchemaToOpenAPI({ rootEntry, schema: fullSchema, openAPIObject = {}, package: packageJson = { name: 'vovk-client' }, }) {
47
+ const paths = {};
48
+ const components = {};
49
+ for (const [segmentName, segmentSchema] of Object.entries(fullSchema.segments ?? {})) {
50
+ for (const c of Object.values(segmentSchema.controllers)) {
51
+ for (const [handlerName, h] of Object.entries(c.handlers ?? {})) {
52
+ if (h.openapi) {
53
+ const [queryValidation, queryComponents] = extractComponents(h?.validation?.query);
54
+ const [bodyValidation, bodyComponents] = extractComponents(h?.validation?.body);
55
+ const [paramsValidation, paramsComponents] = extractComponents(h?.validation?.params);
56
+ const [outputValidation, outputComponents] = extractComponents(h?.validation?.output);
57
+ const [iterationValidation, iterationComponents] = extractComponents(h?.validation?.iteration);
58
+ // TODO: Handle name conflicts?
59
+ Object.assign(components, queryComponents, bodyComponents, paramsComponents, outputComponents, iterationComponents);
60
+ const { ts, rs, py } = (0, createCodeExamples_1.createCodeExamples)({
61
+ package: packageJson,
62
+ handlerName,
63
+ handlerSchema: h,
64
+ controllerSchema: c,
65
+ });
66
+ const queryParameters = queryValidation && 'type' in queryValidation && 'properties' in queryValidation
67
+ ? Object.entries(queryValidation.properties ?? {}).map(([propName, propSchema]) => ({
68
+ name: propName,
69
+ in: 'query',
70
+ required: queryValidation.required ? queryValidation.required.includes(propName) : false,
71
+ schema: propSchema,
72
+ }))
73
+ : null;
74
+ const pathParameters = paramsValidation && 'type' in paramsValidation && 'properties' in paramsValidation
75
+ ? Object.entries(paramsValidation.properties ?? {}).map(([propName, propSchema]) => ({
76
+ name: propName,
77
+ in: 'path',
78
+ required: paramsValidation.required ? paramsValidation.required.includes(propName) : false,
79
+ schema: propSchema,
80
+ }))
81
+ : null;
82
+ const path = '/' +
83
+ [rootEntry.replace(/^\/+|\/+$/g, ''), segmentName, c.prefix, h.path]
84
+ .filter(Boolean)
85
+ .join('/')
86
+ .replace(/:([a-zA-Z0-9_]+)/g, '{$1}');
87
+ paths[path] = paths[path] ?? {};
88
+ const httpMethod = h.httpMethod.toLowerCase();
89
+ paths[path][httpMethod] ??= {};
90
+ paths[path][httpMethod] = {
91
+ ...h.openapi,
92
+ ...paths[path][httpMethod],
93
+ 'x-codeSamples': [
94
+ ...(paths[path][httpMethod]['x-codeSamples'] ?? []),
95
+ ...(h.openapi['x-codeSamples'] ?? []),
96
+ {
97
+ label: 'TypeScript RPC',
98
+ lang: 'typescript',
99
+ source: ts,
100
+ },
101
+ {
102
+ label: 'Python RPC',
103
+ lang: 'python',
104
+ source: py,
105
+ },
106
+ {
107
+ label: 'Rust RPC',
108
+ lang: 'rust',
109
+ source: rs,
110
+ },
111
+ ],
112
+ ...(queryParameters || pathParameters
113
+ ? {
114
+ parameters: h.openapi.parameters ?? [...(queryParameters || []), ...(pathParameters || [])],
115
+ }
116
+ : {}),
117
+ ...(paths[path][httpMethod].parameters
118
+ ? {
119
+ parameters: paths[path][httpMethod].parameters,
120
+ }
121
+ : {}),
122
+ ...(outputValidation && 'type' in outputValidation && 'properties' in outputValidation
123
+ ? {
124
+ responses: {
125
+ 200: {
126
+ description: 'description' in outputValidation ? outputValidation.description : 'Success',
127
+ content: {
128
+ 'application/json': {
129
+ schema: outputValidation,
130
+ },
131
+ },
132
+ },
133
+ ...h.openapi?.responses,
134
+ },
135
+ }
136
+ : {}),
137
+ ...(iterationValidation && 'type' in iterationValidation && 'properties' in iterationValidation
138
+ ? {
139
+ responses: {
140
+ 200: {
141
+ description: 'description' in iterationValidation ? iterationValidation.description : 'JSON Lines response',
142
+ content: {
143
+ 'application/jsonl': {
144
+ schema: {
145
+ ...iterationValidation,
146
+ examples: iterationValidation.examples ?? [
147
+ [
148
+ JSON.stringify((0, json_schema_sampler_1.sample)(iterationValidation)),
149
+ JSON.stringify((0, json_schema_sampler_1.sample)(iterationValidation)),
150
+ JSON.stringify((0, json_schema_sampler_1.sample)(iterationValidation)),
151
+ ].join('\n'),
152
+ ],
153
+ },
154
+ },
155
+ },
156
+ },
157
+ ...h.openapi?.responses,
158
+ },
159
+ }
160
+ : {}),
161
+ ...(paths[path][httpMethod].responses
162
+ ? {
163
+ responses: paths[path][httpMethod].responses,
164
+ }
165
+ : {}),
166
+ ...(bodyValidation && 'type' in bodyValidation && 'properties' in bodyValidation
167
+ ? {
168
+ requestBody: h.openapi?.requestBody ?? {
169
+ description: 'description' in bodyValidation ? bodyValidation.description : 'Request body',
170
+ required: true,
171
+ content: {
172
+ 'application/json': {
173
+ schema: bodyValidation,
174
+ },
175
+ },
176
+ },
177
+ }
178
+ : {}),
179
+ ...(paths[path][httpMethod].requestBody
180
+ ? {
181
+ requestBody: paths[path][httpMethod].requestBody,
182
+ }
183
+ : {}),
184
+ tags: paths[path][httpMethod].tags ?? h.openapi?.tags,
185
+ };
186
+ }
187
+ }
188
+ }
189
+ }
190
+ return {
191
+ ...openAPIObject,
192
+ openapi: '3.1.0',
193
+ info: {
194
+ title: packageJson?.description ?? 'API',
195
+ version: packageJson?.version ?? '0.0.1',
196
+ ...openAPIObject?.info,
197
+ },
198
+ components: {
199
+ schemas: {
200
+ ...(openAPIObject?.components?.schemas ?? components),
201
+ HttpStatus: {
202
+ type: 'integer',
203
+ description: 'HTTP status code',
204
+ enum: Object.keys(types_1.HttpStatus)
205
+ .map((k) => types_1.HttpStatus[k])
206
+ .filter(Boolean)
207
+ .filter((v) => typeof v === 'number'),
208
+ },
209
+ VovkErrorResponse: {
210
+ type: 'object',
211
+ description: 'Vovk error response',
212
+ properties: {
213
+ cause: {
214
+ description: 'Error cause of any shape',
215
+ },
216
+ statusCode: {
217
+ $ref: '#/components/schemas/HttpStatus',
218
+ },
219
+ message: {
220
+ type: 'string',
221
+ description: 'Error message',
222
+ },
223
+ isError: {
224
+ type: 'boolean',
225
+ const: true,
226
+ description: 'Indicates that this object represents an error',
227
+ },
228
+ },
229
+ required: ['statusCode', 'message', 'isError'],
230
+ additionalProperties: false,
231
+ },
232
+ ...openAPIObject?.components?.schemas,
233
+ },
234
+ },
235
+ paths,
236
+ };
237
+ }