vovk-cli 0.0.1-draft.256 → 0.0.1-draft.258

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.
@@ -5,7 +5,7 @@ import type { VovkRequest, VovkStreamAsyncIterable, KnownAny } from 'vovk';
5
5
 
6
6
  export namespace Mixins {
7
7
  <% for (const segment of mixins) { %>
8
- <% console.log(segment); if(segment.meta?.components?.schemas) { %>
8
+ <% if(segment.meta?.components?.schemas) { %>
9
9
  export namespace <%= t._.upperFirst(t._.camelCase(segment.segmentName)) %> {
10
10
  <% for (const [componentName, componentSchema] of Object.entries(segment.meta.components.schemas)) { %>
11
11
  <%- await t.compileJSONSchemaToTypeScriptType(componentSchema, componentName, segment.meta.components) %>
@@ -81,6 +81,7 @@ export default function getConfig({ configPath, cwd }: {
81
81
  file: string;
82
82
  } | {
83
83
  url: string;
84
+ cache?: string;
84
85
  } | {
85
86
  object: import("openapi3-ts/oas31").OpenAPIObject;
86
87
  };
@@ -1,7 +1,25 @@
1
1
  import { compile } from 'json-schema-to-typescript';
2
+ function fixUnresolvedLocalRefs(schema) {
3
+ const schemaStr = JSON.stringify(schema);
4
+ const refs = schemaStr.match(/#\/\$defs\/\w+/g) || [];
5
+ const defs = schema.$defs || {};
6
+ const missingRefs = refs.map((ref) => ref.replace('#/$defs/', '')).filter((defName) => !defs[defName]);
7
+ // Add missing definitions
8
+ if (missingRefs.length > 0) {
9
+ schema.$defs = schema.$defs || {};
10
+ missingRefs.forEach((defName) => {
11
+ schema.$defs[defName] = { tsType: 'unknown' }; // or whatever default you want
12
+ });
13
+ }
14
+ return schema;
15
+ }
2
16
  export async function compileJSONSchemaToTypeScriptType(schema, typeName, components = {}) {
3
17
  if (!schema)
4
18
  return '';
19
+ schema = fixUnresolvedLocalRefs(schema);
20
+ // tsType attribute isn't working with objects that use $ref, so we need to handle it separately
21
+ if ('tsType' in schema && typeof schema.tsType === 'string')
22
+ return `export type ${typeName} = ${schema.tsType};\n`;
5
23
  const tsType = await compile({ ...schema, components }, typeName, {
6
24
  bannerComment: schema.description ? `/**\n * ${schema.description}\n */` : '',
7
25
  style: {
@@ -12,6 +30,8 @@ export async function compileJSONSchemaToTypeScriptType(schema, typeName, compon
12
30
  tabWidth: 2,
13
31
  useTabs: false,
14
32
  trailingComma: 'all',
33
+ unreachableDefinitions: false,
34
+ declareExternallyReferenced: false,
15
35
  },
16
36
  // Don't generate separate interfaces for additionalProperties
17
37
  additionalProperties: false,
@@ -21,205 +41,3 @@ export async function compileJSONSchemaToTypeScriptType(schema, typeName, compon
21
41
  });
22
42
  return tsType;
23
43
  }
24
- /*
25
- // Extend JSONSchema to include custom x-formData property
26
- interface ExtendedJSONSchema extends JSONSchema {
27
- 'x-formData'?: boolean;
28
- [key: string]: any;
29
- }
30
-
31
- interface OpenAPIDocument {
32
- openapi: string;
33
- components?: {
34
- schemas?: Record<string, ExtendedJSONSchema>;
35
- };
36
- [key: string]: any;
37
- }
38
-
39
- /**
40
- * Converts OpenAPI 3.1 component schemas to TypeScript type definitions
41
- * @param oasDoc - The OpenAPI 3.1 document
42
- * @param options - Optional configuration for the TypeScript generation
43
- * @returns A string containing all TypeScript type definitions
44
- * /
45
- export async function oasToTypeScript(
46
- oasDoc: OpenAPIDocument,
47
- options?: {
48
- bannerComment?: string;
49
- style?: {
50
- bracketSpacing?: boolean;
51
- printWidth?: number;
52
- semi?: boolean;
53
- singleQuote?: boolean;
54
- tabWidth?: number;
55
- useTabs?: boolean;
56
- trailingComma?: 'all' | 'es5' | 'none';
57
- };
58
- }
59
- ): Promise<string> {
60
- // Validate that this is an OAS 3.1 document
61
- if (!oasDoc.openapi || !oasDoc.openapi.startsWith('3.1')) {
62
- throw new Error('Document must be an OpenAPI 3.1 specification');
63
- }
64
-
65
- // Extract schemas from components
66
- const schemas = oasDoc.components?.schemas || {};
67
-
68
- if (Object.keys(schemas).length === 0) {
69
- return '// No schemas found in components';
70
- }
71
-
72
- const typeDefinitions: string[] = [];
73
-
74
- // Process each schema
75
- for (const [schemaName, schema] of Object.entries(schemas)) {
76
- try {
77
- // Check if schema has x-formData: true
78
- if (schema['x-formData'] === true) {
79
- // Generate a simple type alias to FormData
80
- typeDefinitions.push(`export type ${schemaName} = FormData;\n`);
81
- continue;
82
- }
83
-
84
- // Handle schema references
85
- const resolvedSchema = resolveSchemaReferences(schema, schemas);
86
-
87
- // Compile to TypeScript
88
- const tsType = await compile(resolvedSchema as JSONSchema, schemaName, {
89
- bannerComment: options?.bannerComment || '',
90
- style: options?.style || {
91
- bracketSpacing: true,
92
- printWidth: 80,
93
- semi: true,
94
- singleQuote: true,
95
- tabWidth: 2,
96
- useTabs: false,
97
- trailingComma: 'all',
98
- },
99
- // Don't generate separate interfaces for additionalProperties
100
- additionalProperties: false,
101
- // Enable strict null checks
102
- strictIndexSignatures: true,
103
- // Don't add schema as comment
104
- $refOptions: {
105
- resolve: {
106
- // Resolve internal references
107
- internal: true,
108
- // Add our custom resolver
109
- custom: {
110
- order: 1,
111
- canRead: (ref: string) => ref.startsWith('#/components/schemas/'),
112
- },
113
- },
114
- },
115
- });
116
-
117
- typeDefinitions.push(tsType);
118
- } catch (error) {
119
- console.error(`Error processing schema "${schemaName}":`, error);
120
- typeDefinitions.push(`// Error processing schema "${schemaName}": ${error.message}`);
121
- }
122
- }
123
-
124
- return typeDefinitions.join('\n');
125
- }
126
-
127
- /**
128
- * Resolves $ref references within a schema
129
- * /
130
- function resolveSchemaReferences(
131
- schema: any,
132
- allSchemas: Record<string, ExtendedJSONSchema>,
133
- visited = new Set<string>()
134
- ): any {
135
- if (!schema || typeof schema !== 'object') {
136
- return schema;
137
- }
138
-
139
- // Handle $ref
140
- if (schema.$ref && typeof schema.$ref === 'string') {
141
- const refPath = schema.$ref.replace('#/components/schemas/', '');
142
-
143
- // Prevent circular references
144
- if (visited.has(refPath)) {
145
- return { type: 'object', additionalProperties: true };
146
- }
147
-
148
- visited.add(refPath);
149
- const referencedSchema = allSchemas[refPath];
150
-
151
- if (referencedSchema) {
152
- return resolveSchemaReferences(referencedSchema, allSchemas, visited);
153
- }
154
-
155
- return schema;
156
- }
157
-
158
- // Handle arrays
159
- if (Array.isArray(schema)) {
160
- return schema.map((item) => resolveSchemaReferences(item, allSchemas, visited));
161
- }
162
-
163
- // Handle objects recursively
164
- const resolved: any = {};
165
- for (const [key, value] of Object.entries(schema)) {
166
- resolved[key] = resolveSchemaReferences(value, allSchemas, visited);
167
- }
168
-
169
- return resolved;
170
- }
171
-
172
- // Example usage:
173
- /*
174
- const oasDoc = {
175
- openapi: '3.1.0',
176
- info: {
177
- title: 'My API',
178
- version: '1.0.0'
179
- },
180
- components: {
181
- schemas: {
182
- User: {
183
- type: 'object',
184
- properties: {
185
- id: { type: 'integer' },
186
- name: { type: 'string' },
187
- email: { type: 'string', format: 'email' },
188
- roles: {
189
- type: 'array',
190
- items: { $ref: '#/components/schemas/Role' }
191
- }
192
- },
193
- required: ['id', 'name', 'email']
194
- },
195
- Role: {
196
- type: 'object',
197
- properties: {
198
- id: { type: 'integer' },
199
- name: { type: 'string' },
200
- permissions: {
201
- type: 'array',
202
- items: { type: 'string' }
203
- }
204
- },
205
- required: ['id', 'name']
206
- },
207
- UploadFileRequest: {
208
- 'x-formData': true,
209
- type: 'object',
210
- properties: {
211
- file: { type: 'string', format: 'binary' },
212
- description: { type: 'string' }
213
- }
214
- }
215
- }
216
- }
217
- };
218
-
219
- const types = await oasToTypeScript(oasDoc);
220
- console.log(types);
221
- // Output will include:
222
- // export interface User { ... }
223
- // export interface Role { ... }
224
- // export type UploadFileRequest = FormData;
225
- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.256",
3
+ "version": "0.0.1-draft.258",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "homepage": "https://vovk.dev",
37
37
  "peerDependencies": {
38
- "vovk": "^3.0.0-draft.292"
38
+ "vovk": "^3.0.0-draft.296"
39
39
  },
40
40
  "optionalDependencies": {
41
41
  "vovk-python": "^0.0.1-draft.41"