@povio/openapi-codegen-cli 3.1.0-rc.3 → 3.1.0-rc.5
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/metro.cjs +5280 -0
- package/dist/metro.d.mts +4 -2
- package/dist/metro.mjs +3 -1
- package/dist/{openapi-BkC5yZ-W.d.mts → openapi-source.runner-BSIrB6ny.d.mts} +26 -1
- package/dist/openapi-source.runner-wLs5vqw6.mjs +705 -0
- package/dist/sh.mjs +1 -1
- package/dist/tiny.d.mts +3 -20
- package/dist/tiny.mjs +1 -649
- package/dist/vite.d.mts +4 -2
- package/dist/vite.mjs +3 -1
- package/package.json +3 -2
- package/dist/openapi-source.runner-D19XnvMe.mjs +0 -39
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path, { join } from "path";
|
|
3
|
+
import { pathToFileURL } from "url";
|
|
4
|
+
import { access, readdir } from "fs/promises";
|
|
5
|
+
|
|
6
|
+
//#region src/tiny/openapi.ts
|
|
7
|
+
async function importRuntimeModule(specifier) {
|
|
8
|
+
return new Function("specifier", "return import(specifier)")(specifier);
|
|
9
|
+
}
|
|
10
|
+
const PAGINATED_OUTPUT_SUFFIX = "PaginateOutput";
|
|
11
|
+
const PAGINATED_RESPONSE_SUFFIX = "PaginateResponse";
|
|
12
|
+
const PAGINATION_RESPONSE_OUTPUT_SUFFIX = "PaginationResponseOutput";
|
|
13
|
+
const PAGINATED_ITEM_SUFFIX = "PaginateItem";
|
|
14
|
+
const PAGINATED_ITEM_OUTPUT_SUFFIX = "PaginateItemOutput";
|
|
15
|
+
const PAGINATION_DTO_SCHEMA_NAME = "PaginationDto";
|
|
16
|
+
const PAGINATION_PROPERTY_NAMES = [
|
|
17
|
+
"page",
|
|
18
|
+
"cursor",
|
|
19
|
+
"nextCursor",
|
|
20
|
+
"limit",
|
|
21
|
+
"totalItems"
|
|
22
|
+
];
|
|
23
|
+
const OPENAPI_31_ONLY_KEYS = new Set([
|
|
24
|
+
"$schema",
|
|
25
|
+
"$id",
|
|
26
|
+
"$vocabulary",
|
|
27
|
+
"$dynamicAnchor",
|
|
28
|
+
"$dynamicRef",
|
|
29
|
+
"$defs",
|
|
30
|
+
"jsonSchemaDialect",
|
|
31
|
+
"unevaluatedItems",
|
|
32
|
+
"unevaluatedProperties",
|
|
33
|
+
"dependentRequired",
|
|
34
|
+
"dependentSchemas",
|
|
35
|
+
"prefixItems",
|
|
36
|
+
"propertyNames",
|
|
37
|
+
"contains",
|
|
38
|
+
"minContains",
|
|
39
|
+
"maxContains",
|
|
40
|
+
"contentEncoding",
|
|
41
|
+
"contentMediaType",
|
|
42
|
+
"contentSchema"
|
|
43
|
+
]);
|
|
44
|
+
const openApiSchemaNames = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
function resolveOpenApiOutputPath({ argv = process.argv, cwd = process.cwd(), defaultOutput, env = process.env }) {
|
|
46
|
+
const outputFlagIndex = argv.indexOf("--output");
|
|
47
|
+
const output = (outputFlagIndex !== -1 ? argv[outputFlagIndex + 1] : void 0) ?? env.TINY_OPENAPI_OUTPUT ?? defaultOutput;
|
|
48
|
+
return path.resolve(cwd, output);
|
|
49
|
+
}
|
|
50
|
+
async function generateOpenApiFile(options) {
|
|
51
|
+
const outputPath = resolveOpenApiOutputPath(options);
|
|
52
|
+
const spec = await options.generateOpenApiSpec();
|
|
53
|
+
const output = `${JSON.stringify(spec, null, 2)}\n`;
|
|
54
|
+
if (fs.existsSync(outputPath) && fs.readFileSync(outputPath, "utf8") === output) return {
|
|
55
|
+
outputPath,
|
|
56
|
+
changed: false
|
|
57
|
+
};
|
|
58
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
59
|
+
fs.writeFileSync(outputPath, output);
|
|
60
|
+
return {
|
|
61
|
+
outputPath,
|
|
62
|
+
changed: true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function defineOpenApiSchemas(schemas) {
|
|
66
|
+
return schemas;
|
|
67
|
+
}
|
|
68
|
+
function collectExtraSchemas(modules) {
|
|
69
|
+
return Object.values(modules).reduce((schemas, module) => {
|
|
70
|
+
Object.assign(schemas, module.extraSchemas ?? {});
|
|
71
|
+
return schemas;
|
|
72
|
+
}, {});
|
|
73
|
+
}
|
|
74
|
+
function namedOpenApiSchema(schema, name) {
|
|
75
|
+
openApiSchemaNames.set(schema, name);
|
|
76
|
+
return schema;
|
|
77
|
+
}
|
|
78
|
+
function namedOpenApiRequestSchema(schema, name) {
|
|
79
|
+
return namedOpenApiSchema(schema, `${name}Request`);
|
|
80
|
+
}
|
|
81
|
+
function namedOpenApiResponseSchema(schema, name) {
|
|
82
|
+
return namedOpenApiSchema(schema, `${name}Response`);
|
|
83
|
+
}
|
|
84
|
+
function namedOpenApiOutputSchema(schema, name) {
|
|
85
|
+
return namedOpenApiResponseSchema(schema, name);
|
|
86
|
+
}
|
|
87
|
+
function namedControllerActionSchema(schema, controller, action, suffix) {
|
|
88
|
+
return namedOpenApiSchema(schema, `${controller}Controller${toPascalCase(action)}${suffix}`);
|
|
89
|
+
}
|
|
90
|
+
function namedControllerActionInputDtoSchema(schema, controller, action) {
|
|
91
|
+
return namedControllerActionSchema(schema, controller, action, "Request");
|
|
92
|
+
}
|
|
93
|
+
function getOpenApiSchemaName(schema) {
|
|
94
|
+
return typeof schema === "object" && schema !== null ? openApiSchemaNames.get(schema) : void 0;
|
|
95
|
+
}
|
|
96
|
+
function isObject(value) {
|
|
97
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
98
|
+
}
|
|
99
|
+
function getContractProcedureData(router) {
|
|
100
|
+
if (!isObject(router) || !isObject(router["~orpc"])) return;
|
|
101
|
+
const data = router["~orpc"];
|
|
102
|
+
if (!isObject(data.route)) return;
|
|
103
|
+
return {
|
|
104
|
+
inputSchema: data.inputSchema,
|
|
105
|
+
meta: data.meta,
|
|
106
|
+
outputSchema: data.outputSchema,
|
|
107
|
+
route: {
|
|
108
|
+
inputStructure: typeof data.route.inputStructure === "string" ? data.route.inputStructure : void 0,
|
|
109
|
+
method: typeof data.route.method === "string" ? data.route.method : void 0,
|
|
110
|
+
operationId: typeof data.route.operationId === "string" ? data.route.operationId : void 0,
|
|
111
|
+
path: typeof data.route.path === "string" ? data.route.path : void 0,
|
|
112
|
+
successStatus: typeof data.route.successStatus === "number" ? data.route.successStatus : void 0
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function isContractProcedure(router) {
|
|
117
|
+
return Boolean(getContractProcedureData(router));
|
|
118
|
+
}
|
|
119
|
+
function routerEntries(router) {
|
|
120
|
+
return isObject(router) ? Object.entries(router) : [];
|
|
121
|
+
}
|
|
122
|
+
function asStringArray(value) {
|
|
123
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
|
|
124
|
+
}
|
|
125
|
+
function isNullSchema(value) {
|
|
126
|
+
return isObject(value) && value.type === "null";
|
|
127
|
+
}
|
|
128
|
+
function isNullableOnlySchema(value) {
|
|
129
|
+
return isObject(value) && value.nullable === true && Object.keys(value).every((key) => key === "nullable");
|
|
130
|
+
}
|
|
131
|
+
function toOpenAPI30Schema(value) {
|
|
132
|
+
if (Array.isArray(value)) return value.map(toOpenAPI30Schema);
|
|
133
|
+
if (!isObject(value)) return value;
|
|
134
|
+
const next = {};
|
|
135
|
+
for (const [key, rawValue] of Object.entries(value)) {
|
|
136
|
+
if (OPENAPI_31_ONLY_KEYS.has(key)) continue;
|
|
137
|
+
if (key === "const") {
|
|
138
|
+
next.enum = [rawValue];
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
next[key] = toOpenAPI30Schema(rawValue);
|
|
142
|
+
}
|
|
143
|
+
if (Array.isArray(next.type)) {
|
|
144
|
+
const types = next.type.filter((item) => item !== "null");
|
|
145
|
+
if (types.length !== next.type.length) next.nullable = true;
|
|
146
|
+
if (types.length === 1) {
|
|
147
|
+
const [type] = types;
|
|
148
|
+
next.type = type;
|
|
149
|
+
} else if (types.length > 1) {
|
|
150
|
+
delete next.type;
|
|
151
|
+
next.anyOf = types.map((type) => ({ type }));
|
|
152
|
+
} else delete next.type;
|
|
153
|
+
}
|
|
154
|
+
for (const keyword of ["anyOf", "oneOf"]) {
|
|
155
|
+
const branches = next[keyword];
|
|
156
|
+
if (Array.isArray(branches) && branches.some((item) => isNullSchema(item) || isNullableOnlySchema(item))) {
|
|
157
|
+
const nonNullBranches = branches.filter((item) => !isNullSchema(item) && !isNullableOnlySchema(item));
|
|
158
|
+
next.nullable = true;
|
|
159
|
+
if (nonNullBranches.length === 1 && isObject(nonNullBranches[0])) {
|
|
160
|
+
delete next[keyword];
|
|
161
|
+
Object.assign(next, nonNullBranches[0]);
|
|
162
|
+
next.nullable = true;
|
|
163
|
+
} else next[keyword] = nonNullBranches;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (next.type === "null") {
|
|
167
|
+
delete next.type;
|
|
168
|
+
next.nullable = true;
|
|
169
|
+
}
|
|
170
|
+
if (typeof next.$ref === "string" && next.nullable === true) {
|
|
171
|
+
const { $ref, ...rest } = next;
|
|
172
|
+
return {
|
|
173
|
+
...rest,
|
|
174
|
+
allOf: [{ $ref }]
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return next;
|
|
178
|
+
}
|
|
179
|
+
function stripNoContentResponseBodies(spec) {
|
|
180
|
+
if (!isObject(spec.paths)) return;
|
|
181
|
+
for (const pathItem of Object.values(spec.paths)) {
|
|
182
|
+
if (!isObject(pathItem)) continue;
|
|
183
|
+
for (const operation of Object.values(pathItem)) {
|
|
184
|
+
if (!isObject(operation) || !isObject(operation.responses)) continue;
|
|
185
|
+
const noContentResponse = operation.responses["204"];
|
|
186
|
+
if (isObject(noContentResponse)) delete noContentResponse.content;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function isProcedureMeta(meta) {
|
|
191
|
+
return isObject(meta) && typeof meta.bl === "string";
|
|
192
|
+
}
|
|
193
|
+
function operationKey(method, routePath) {
|
|
194
|
+
return `${method.toLowerCase()} ${routePath}`;
|
|
195
|
+
}
|
|
196
|
+
function toPascalCase(value) {
|
|
197
|
+
return value.replace(/(^|[-_\s]+)([a-zA-Z0-9]?)/g, (_, _separator, next) => next.toUpperCase());
|
|
198
|
+
}
|
|
199
|
+
function isZodSchema(value) {
|
|
200
|
+
return isObject(value) && isObject(value["~standard"]) && value["~standard"].vendor === "zod" && isObject(value._zod) && isObject(value._zod.def);
|
|
201
|
+
}
|
|
202
|
+
function schemaExportName(moduleName, exportName, schema, getSchemaName = getOpenApiSchemaName) {
|
|
203
|
+
const explicitName = getSchemaName(schema);
|
|
204
|
+
if (explicitName) return explicitName;
|
|
205
|
+
const schemaName = exportName.replace(/Schema$/, "").replace(/DTO$/u, "");
|
|
206
|
+
const modulePrefix = toPascalCase(moduleName);
|
|
207
|
+
const singularModulePrefix = modulePrefix.endsWith("s") ? modulePrefix.slice(0, -1) : modulePrefix;
|
|
208
|
+
return moduleName === "common" || schemaName.startsWith(modulePrefix) || schemaName.startsWith(singularModulePrefix) ? schemaName : `${modulePrefix}${schemaName}`;
|
|
209
|
+
}
|
|
210
|
+
function modelSchemaExportName(exportName) {
|
|
211
|
+
return exportName.replace(/Schema$/, "");
|
|
212
|
+
}
|
|
213
|
+
function sharedSchemaExportName(exportName) {
|
|
214
|
+
return exportName.replace(/Schema$/, "");
|
|
215
|
+
}
|
|
216
|
+
async function collectModelSchemaExports(options) {
|
|
217
|
+
const apiSchemaGroups = options.apiRoot ? await collectApiModelSchemaExports(options.apiRoot) : [];
|
|
218
|
+
const dbSchemaExports = options.dbTablesRoot ? await collectDbTableModelSchemaExports(options.dbTablesRoot) : [];
|
|
219
|
+
return [...apiSchemaGroups, ...dbSchemaExports];
|
|
220
|
+
}
|
|
221
|
+
async function collectApiModelSchemaExports(apiRoot) {
|
|
222
|
+
const entries = await readdir(apiRoot, { withFileTypes: true });
|
|
223
|
+
return (await Promise.all(entries.filter((item) => item.isDirectory()).sort((a, b) => a.name.localeCompare(b.name)).map((entry) => collectModuleModelSchemaExports(apiRoot, entry.name)))).flat();
|
|
224
|
+
}
|
|
225
|
+
async function collectModuleModelSchemaExports(apiRoot, moduleName) {
|
|
226
|
+
const modelsPath = join(apiRoot, moduleName, `${moduleName}.models.ts`);
|
|
227
|
+
try {
|
|
228
|
+
await access(modelsPath);
|
|
229
|
+
} catch {
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
const models = await import(
|
|
233
|
+
/* @vite-ignore */
|
|
234
|
+
pathToFileURL(modelsPath).href
|
|
235
|
+
);
|
|
236
|
+
const schemas = [];
|
|
237
|
+
for (const [exportName, schema] of Object.entries(models)) if (exportName.endsWith("Schema") && isZodSchema(schema)) schemas.push({
|
|
238
|
+
moduleName,
|
|
239
|
+
name: modelSchemaExportName(exportName),
|
|
240
|
+
schema
|
|
241
|
+
});
|
|
242
|
+
return schemas;
|
|
243
|
+
}
|
|
244
|
+
async function collectDbTableModelSchemaExports(tablesRoot) {
|
|
245
|
+
const tableEntries = await readdir(tablesRoot, { withFileTypes: true });
|
|
246
|
+
return (await Promise.all(tableEntries.filter((item) => item.isDirectory()).sort((a, b) => a.name.localeCompare(b.name)).map((entry) => collectDbTableModelSchemaExport(tablesRoot, entry.name)))).flat();
|
|
247
|
+
}
|
|
248
|
+
async function collectDbTableModelSchemaExport(tablesRoot, tableName) {
|
|
249
|
+
const schemaPath = join(tablesRoot, tableName, `${tableName}.schema.ts`);
|
|
250
|
+
try {
|
|
251
|
+
await access(schemaPath);
|
|
252
|
+
} catch {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
const exports = await import(
|
|
256
|
+
/* @vite-ignore */
|
|
257
|
+
pathToFileURL(schemaPath).href
|
|
258
|
+
);
|
|
259
|
+
const schemas = [];
|
|
260
|
+
for (const [exportName, schema] of Object.entries(exports)) if (exportName.endsWith("TypeSchema") && isZodSchema(schema)) schemas.push({
|
|
261
|
+
moduleName: "db",
|
|
262
|
+
name: sharedSchemaExportName(exportName),
|
|
263
|
+
schema
|
|
264
|
+
});
|
|
265
|
+
return schemas;
|
|
266
|
+
}
|
|
267
|
+
function toOpenAPIAclRule(rule) {
|
|
268
|
+
const [subject, action] = rule.split(":");
|
|
269
|
+
return {
|
|
270
|
+
action,
|
|
271
|
+
subject: toPascalCase(subject)
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function collectOperationMeta(router, routerPath = [], operationMeta = /* @__PURE__ */ new Map()) {
|
|
275
|
+
const procedure = getContractProcedureData(router);
|
|
276
|
+
if (procedure) {
|
|
277
|
+
const { meta, route } = procedure;
|
|
278
|
+
if (route.method && route.path && isProcedureMeta(meta)) operationMeta.set(operationKey(route.method, route.path), {
|
|
279
|
+
meta,
|
|
280
|
+
path: routerPath,
|
|
281
|
+
routeOperationId: route.operationId
|
|
282
|
+
});
|
|
283
|
+
return operationMeta;
|
|
284
|
+
}
|
|
285
|
+
for (const [name, child] of routerEntries(router)) collectOperationMeta(child, [...routerPath, name], operationMeta);
|
|
286
|
+
return operationMeta;
|
|
287
|
+
}
|
|
288
|
+
function getObjectPropertySchema(schema, property) {
|
|
289
|
+
if (!isZodSchema(schema) || schema._zod.def.type !== "object") return;
|
|
290
|
+
const { _zod: { def: { shape } } } = schema;
|
|
291
|
+
if (!isObject(shape)) return;
|
|
292
|
+
const propertySchema = shape[property];
|
|
293
|
+
return isZodSchema(propertySchema) ? propertySchema : void 0;
|
|
294
|
+
}
|
|
295
|
+
function routeHasPathParameters(routePath) {
|
|
296
|
+
return typeof routePath === "string" && /\{[^}]+\}/u.test(routePath);
|
|
297
|
+
}
|
|
298
|
+
function getProcedureInputSchemaRole(route) {
|
|
299
|
+
if (routeHasPathParameters(route.path)) return "Params";
|
|
300
|
+
return route.method?.toUpperCase() === "GET" ? "Query" : "Request";
|
|
301
|
+
}
|
|
302
|
+
function procedureSchemaName(procedureName, role) {
|
|
303
|
+
if (procedureName.endsWith(role)) return procedureName;
|
|
304
|
+
return `${procedureName}${role}`;
|
|
305
|
+
}
|
|
306
|
+
function addContractSchema(schemas, schema, name, getSchemaName, strategy) {
|
|
307
|
+
if (!schema) return;
|
|
308
|
+
schemas[getSchemaName(schema) ?? name] = {
|
|
309
|
+
schema,
|
|
310
|
+
...strategy ? { strategy } : {}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function collectContractSchemas(router, routerPath = [], schemas = {}, getSchemaName = getOpenApiSchemaName) {
|
|
314
|
+
const procedure = getContractProcedureData(router);
|
|
315
|
+
if (procedure) {
|
|
316
|
+
const procedureName = routerPath.map(toPascalCase).join("");
|
|
317
|
+
const { inputSchema, outputSchema, route } = procedure;
|
|
318
|
+
if (inputSchema) if (route.inputStructure === "detailed") {
|
|
319
|
+
addContractSchema(schemas, getObjectPropertySchema(inputSchema, "params"), procedureSchemaName(procedureName, "Params"), getSchemaName);
|
|
320
|
+
addContractSchema(schemas, getObjectPropertySchema(inputSchema, "query"), procedureSchemaName(procedureName, "Query"), getSchemaName);
|
|
321
|
+
addContractSchema(schemas, getObjectPropertySchema(inputSchema, "body") ?? inputSchema, procedureSchemaName(procedureName, "Request"), getSchemaName);
|
|
322
|
+
} else addContractSchema(schemas, inputSchema, procedureSchemaName(procedureName, getProcedureInputSchemaRole(route)), getSchemaName);
|
|
323
|
+
if (outputSchema && route.successStatus !== 204) addContractSchema(schemas, outputSchema, procedureSchemaName(procedureName, "Response"), getSchemaName, "output");
|
|
324
|
+
return schemas;
|
|
325
|
+
}
|
|
326
|
+
for (const [name, child] of routerEntries(router)) collectContractSchemas(child, [...routerPath, name], schemas, getSchemaName);
|
|
327
|
+
return schemas;
|
|
328
|
+
}
|
|
329
|
+
function collectContractSchemaRoots(router, roots = /* @__PURE__ */ new Set()) {
|
|
330
|
+
const procedure = getContractProcedureData(router);
|
|
331
|
+
if (procedure) {
|
|
332
|
+
const { inputSchema, outputSchema, route } = procedure;
|
|
333
|
+
if (inputSchema) roots.add(inputSchema);
|
|
334
|
+
if (outputSchema && route.successStatus !== 204) roots.add(outputSchema);
|
|
335
|
+
return roots;
|
|
336
|
+
}
|
|
337
|
+
for (const [, child] of routerEntries(router)) collectContractSchemaRoots(child, roots);
|
|
338
|
+
return roots;
|
|
339
|
+
}
|
|
340
|
+
function visitZodSchema(schema, visit, seen = /* @__PURE__ */ new Set()) {
|
|
341
|
+
if (seen.has(schema)) return;
|
|
342
|
+
seen.add(schema);
|
|
343
|
+
visit(schema);
|
|
344
|
+
const visitValue = (value) => {
|
|
345
|
+
if (isZodSchema(value)) {
|
|
346
|
+
visitZodSchema(value, visit, seen);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (Array.isArray(value)) {
|
|
350
|
+
value.forEach(visitValue);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (isObject(value)) Object.values(value).forEach(visitValue);
|
|
354
|
+
};
|
|
355
|
+
const { def } = schema._zod;
|
|
356
|
+
Object.values(def).forEach(visitValue);
|
|
357
|
+
if (typeof def.getter === "function") {
|
|
358
|
+
const lazyValue = def.getter();
|
|
359
|
+
if (isZodSchema(lazyValue)) visitZodSchema(lazyValue, visit, seen);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function collectSchemaRegistryRoots(registry) {
|
|
363
|
+
return Object.values(registry).reduce((schemas, entry) => {
|
|
364
|
+
if ("schema" in entry && entry.schema) schemas.add(entry.schema);
|
|
365
|
+
return schemas;
|
|
366
|
+
}, /* @__PURE__ */ new Set());
|
|
367
|
+
}
|
|
368
|
+
function modelSchemaNameEntries(modelSchemas) {
|
|
369
|
+
const schemaNameBySchema = /* @__PURE__ */ new Map();
|
|
370
|
+
for (const { name, schema } of modelSchemas) {
|
|
371
|
+
const existingName = schemaNameBySchema.get(schema);
|
|
372
|
+
if (!existingName || name.length < existingName.length) schemaNameBySchema.set(schema, name);
|
|
373
|
+
}
|
|
374
|
+
return schemaNameBySchema;
|
|
375
|
+
}
|
|
376
|
+
function createModelSchemaNameGetter(modelSchemas, getSchemaName = getOpenApiSchemaName) {
|
|
377
|
+
const schemaNameBySchema = modelSchemaNameEntries(modelSchemas);
|
|
378
|
+
return (schema) => (isZodSchema(schema) ? schemaNameBySchema.get(schema) : void 0) ?? getSchemaName(schema);
|
|
379
|
+
}
|
|
380
|
+
async function collectReachableModelSchemas(router, options = {}) {
|
|
381
|
+
const excludedSchemas = options.excludedSchemas ?? /* @__PURE__ */ new Set();
|
|
382
|
+
const modelSchemas = options.modelSchemas ?? await collectModelSchemaExports(options);
|
|
383
|
+
const schemaNameBySchema = modelSchemaNameEntries(modelSchemas);
|
|
384
|
+
const routeRoots = collectContractSchemaRoots(router);
|
|
385
|
+
const reachableSchemas = {};
|
|
386
|
+
for (const { moduleName, name, schema } of modelSchemas) if ((moduleName === "common" || name.endsWith("SortableKey") || name.endsWith("OrderParamEnum")) && !excludedSchemas.has(schema)) reachableSchemas[name] = { schema };
|
|
387
|
+
for (const root of routeRoots) {
|
|
388
|
+
if (!isZodSchema(root)) continue;
|
|
389
|
+
visitZodSchema(root, (schema) => {
|
|
390
|
+
if (routeRoots.has(schema) || excludedSchemas.has(schema)) return;
|
|
391
|
+
const name = schemaNameBySchema.get(schema);
|
|
392
|
+
if (name) reachableSchemas[name] = { schema };
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
return reachableSchemas;
|
|
396
|
+
}
|
|
397
|
+
function compactTagName(value) {
|
|
398
|
+
return value.replace(/[^a-zA-Z0-9]/g, "");
|
|
399
|
+
}
|
|
400
|
+
function getModuleOpenApiController(apiModules, moduleName) {
|
|
401
|
+
const module = apiModules[moduleName];
|
|
402
|
+
return module?.openApiController ?? `${compactTagName(module?.openApiTag ?? toPascalCase(moduleName))}Controller`;
|
|
403
|
+
}
|
|
404
|
+
function getOperationController(apiModules, operationPath) {
|
|
405
|
+
const [moduleName, controllerSegment] = operationPath;
|
|
406
|
+
if (!moduleName) return;
|
|
407
|
+
if (!controllerSegment || operationPath.length === 2) return getModuleOpenApiController(apiModules, moduleName);
|
|
408
|
+
return `${getModuleOpenApiController(apiModules, moduleName).replace(/Controller$/, "")}${toPascalCase(controllerSegment)}Controller`;
|
|
409
|
+
}
|
|
410
|
+
function getOperationAction(operationPath) {
|
|
411
|
+
return operationPath.at(-1);
|
|
412
|
+
}
|
|
413
|
+
function getDerivedOperationId(apiModules, info) {
|
|
414
|
+
const controller = getOperationController(apiModules, info.path);
|
|
415
|
+
const action = getOperationAction(info.path);
|
|
416
|
+
return controller && action ? `${controller}_${action}` : void 0;
|
|
417
|
+
}
|
|
418
|
+
function applyOperationMeta(spec, operationMeta, apiModules) {
|
|
419
|
+
if (!isObject(spec.paths)) return;
|
|
420
|
+
for (const [routePath, pathItem] of Object.entries(spec.paths)) {
|
|
421
|
+
if (!isObject(pathItem)) continue;
|
|
422
|
+
for (const [method, operation] of Object.entries(pathItem)) {
|
|
423
|
+
if (!isObject(operation)) continue;
|
|
424
|
+
const info = operationMeta.get(operationKey(method, routePath));
|
|
425
|
+
if (!info) continue;
|
|
426
|
+
operation.operationId = info.routeOperationId ?? getDerivedOperationId(apiModules, info) ?? operation.operationId;
|
|
427
|
+
const { meta } = info;
|
|
428
|
+
operation["x-bl"] = meta.bl;
|
|
429
|
+
if (meta.acl) {
|
|
430
|
+
operation["x-acl"] = meta.acl.map(toOpenAPIAclRule);
|
|
431
|
+
operation.responses = {
|
|
432
|
+
...isObject(operation.responses) ? operation.responses : {},
|
|
433
|
+
"401": { description: "Unauthorized" },
|
|
434
|
+
"403": { description: "Forbidden" }
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function findEnumNames(value) {
|
|
441
|
+
if (!isObject(value)) return;
|
|
442
|
+
const enumNames = value["x-enumNames"];
|
|
443
|
+
if (Array.isArray(enumNames) && enumNames.every((item) => typeof item === "string")) return enumNames;
|
|
444
|
+
for (const keyword of [
|
|
445
|
+
"allOf",
|
|
446
|
+
"anyOf",
|
|
447
|
+
"oneOf"
|
|
448
|
+
]) {
|
|
449
|
+
const schemas = value[keyword];
|
|
450
|
+
if (!Array.isArray(schemas)) continue;
|
|
451
|
+
for (const schema of schemas) {
|
|
452
|
+
const nestedEnumNames = findEnumNames(schema);
|
|
453
|
+
if (nestedEnumNames) return nestedEnumNames;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function getStringEnumValues(schema) {
|
|
458
|
+
const { enum: enumValues } = schema;
|
|
459
|
+
if (!Array.isArray(enumValues) || enumValues.length === 0) return;
|
|
460
|
+
return enumValues.every((item) => typeof item === "string") ? enumValues : void 0;
|
|
461
|
+
}
|
|
462
|
+
function applyEnumExtensions(value) {
|
|
463
|
+
if (Array.isArray(value)) {
|
|
464
|
+
value.forEach(applyEnumExtensions);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
if (!isObject(value)) return;
|
|
468
|
+
const enumNames = getStringEnumValues(value);
|
|
469
|
+
if (enumNames && !Array.isArray(value["x-enumNames"])) value["x-enumNames"] = enumNames;
|
|
470
|
+
Object.values(value).forEach(applyEnumExtensions);
|
|
471
|
+
}
|
|
472
|
+
function findComponentEnumNames(spec, name) {
|
|
473
|
+
const { components } = spec;
|
|
474
|
+
if (!isObject(components) || !isObject(components.schemas)) return;
|
|
475
|
+
const schema = components.schemas[name];
|
|
476
|
+
if (!isObject(schema)) return;
|
|
477
|
+
return findEnumNames(schema) ?? getStringEnumValues(schema);
|
|
478
|
+
}
|
|
479
|
+
function applyParameterExtensions(spec, realBackendSortableSchemaNames = /* @__PURE__ */ new Map()) {
|
|
480
|
+
if (!isObject(spec.paths)) return;
|
|
481
|
+
for (const pathItem of Object.values(spec.paths)) {
|
|
482
|
+
if (!isObject(pathItem)) continue;
|
|
483
|
+
for (const operation of Object.values(pathItem)) {
|
|
484
|
+
if (!isObject(operation) || !Array.isArray(operation.parameters)) continue;
|
|
485
|
+
const [tag] = Array.isArray(operation.tags) ? operation.tags : [];
|
|
486
|
+
const sortableSchemaName = typeof tag === "string" ? realBackendSortableSchemaNames.get(tag) ?? `${toPascalCase(tag)}SortableKey` : void 0;
|
|
487
|
+
const sortableEnumNames = sortableSchemaName ? findComponentEnumNames(spec, sortableSchemaName) : void 0;
|
|
488
|
+
for (const parameter of operation.parameters) {
|
|
489
|
+
if (!isObject(parameter) || parameter.in !== "query") continue;
|
|
490
|
+
if (parameter.name === "filter" && parameter.required !== true) parameter.required = false;
|
|
491
|
+
const enumNames = findEnumNames(parameter.schema) ?? (parameter.name === "order" ? sortableEnumNames : void 0);
|
|
492
|
+
if (enumNames) parameter["x-enumNames"] = enumNames;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
function getModuleOpenApiTag(apiModules, moduleName) {
|
|
498
|
+
return apiModules[moduleName]?.openApiTag ?? moduleName;
|
|
499
|
+
}
|
|
500
|
+
function applyRobodevModuleExtensions(spec, moduleExtensions, apiModules) {
|
|
501
|
+
if (moduleExtensions.size === 0) return;
|
|
502
|
+
const existingTags = Array.isArray(spec.tags) ? spec.tags.filter(isObject) : [];
|
|
503
|
+
const tagsByName = /* @__PURE__ */ new Map();
|
|
504
|
+
for (const tag of existingTags) if (typeof tag.name === "string") tagsByName.set(tag.name, tag);
|
|
505
|
+
for (const [moduleName, metadata] of moduleExtensions) {
|
|
506
|
+
const tagName = getModuleOpenApiTag(apiModules, moduleName);
|
|
507
|
+
const tag = tagsByName.get(tagName) ?? { name: tagName };
|
|
508
|
+
if (metadata.hidden) tag["x-robodev-hidden"] = true;
|
|
509
|
+
if (metadata.tables.length > 0) tag["x-robodev-owned-tables"] = metadata.tables;
|
|
510
|
+
if (metadata.roles.length > 0) tag["x-robodev-roles"] = metadata.roles;
|
|
511
|
+
tagsByName.set(tagName, tag);
|
|
512
|
+
}
|
|
513
|
+
spec.tags = [...tagsByName.values()];
|
|
514
|
+
}
|
|
515
|
+
function applyRobodevUserRolesExtension(spec, userRoles = []) {
|
|
516
|
+
spec["x-robodev-user-roles"] = userRoles.map((role) => ({
|
|
517
|
+
name: role.name,
|
|
518
|
+
description: role.description,
|
|
519
|
+
...role.isDefault ? { isDefault: true } : {}
|
|
520
|
+
}));
|
|
521
|
+
}
|
|
522
|
+
function collectOperationTags(spec) {
|
|
523
|
+
const tags = /* @__PURE__ */ new Set();
|
|
524
|
+
if (!isObject(spec.paths)) return tags;
|
|
525
|
+
for (const pathItem of Object.values(spec.paths)) {
|
|
526
|
+
if (!isObject(pathItem)) continue;
|
|
527
|
+
for (const operation of Object.values(pathItem)) {
|
|
528
|
+
if (!isObject(operation)) continue;
|
|
529
|
+
asStringArray(operation.tags).forEach((tag) => tags.add(tag));
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return tags;
|
|
533
|
+
}
|
|
534
|
+
function getRobodevModuleRoles(hidden, explicitRoles, moduleHasOperations, defaultRoles) {
|
|
535
|
+
if (hidden) return [];
|
|
536
|
+
if (explicitRoles) return [...explicitRoles];
|
|
537
|
+
return moduleHasOperations ? [...defaultRoles] : [];
|
|
538
|
+
}
|
|
539
|
+
function schemaComponentRef(name) {
|
|
540
|
+
return { $ref: `#/components/schemas/${name}` };
|
|
541
|
+
}
|
|
542
|
+
function getComponentSchemas(spec) {
|
|
543
|
+
const { components } = spec;
|
|
544
|
+
if (!isObject(components) || !isObject(components.schemas)) return null;
|
|
545
|
+
return components.schemas;
|
|
546
|
+
}
|
|
547
|
+
function getPaginatedItemSchema(schema) {
|
|
548
|
+
const { properties } = schema;
|
|
549
|
+
if (!isObject(properties) || !PAGINATION_PROPERTY_NAMES.every((name) => name in properties)) return null;
|
|
550
|
+
const { items } = properties;
|
|
551
|
+
if (!isObject(items) || items.type !== "array" || !isObject(items.items)) return null;
|
|
552
|
+
return items.items;
|
|
553
|
+
}
|
|
554
|
+
function applyPaginatedItemSchemas(spec) {
|
|
555
|
+
const schemas = getComponentSchemas(spec);
|
|
556
|
+
if (!schemas) return;
|
|
557
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
558
|
+
if (!(name.endsWith(PAGINATED_OUTPUT_SUFFIX) || name.endsWith(PAGINATED_RESPONSE_SUFFIX) || name.endsWith(PAGINATION_RESPONSE_OUTPUT_SUFFIX)) || !isObject(schema)) continue;
|
|
559
|
+
const itemSchema = getPaginatedItemSchema(schema);
|
|
560
|
+
if (!itemSchema) continue;
|
|
561
|
+
const itemName = name.endsWith(PAGINATION_RESPONSE_OUTPUT_SUFFIX) ? name.replace(new RegExp(`${PAGINATION_RESPONSE_OUTPUT_SUFFIX}$`), PAGINATED_ITEM_OUTPUT_SUFFIX) : name.replace(new RegExp(`${PAGINATED_OUTPUT_SUFFIX}$`), PAGINATED_ITEM_SUFFIX).replace(new RegExp(`${PAGINATED_RESPONSE_SUFFIX}$`), PAGINATED_ITEM_SUFFIX);
|
|
562
|
+
schemas[itemName] = { allOf: [itemSchema] };
|
|
563
|
+
schemas[name] = { allOf: [schemaComponentRef(PAGINATION_DTO_SCHEMA_NAME), {
|
|
564
|
+
type: "object",
|
|
565
|
+
properties: { items: {
|
|
566
|
+
type: "array",
|
|
567
|
+
items: schemaComponentRef(itemName)
|
|
568
|
+
} },
|
|
569
|
+
required: ["items"]
|
|
570
|
+
}] };
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function toOpenAPI30Document(spec) {
|
|
574
|
+
const converted = toOpenAPI30Schema(spec);
|
|
575
|
+
converted.openapi = "3.0.3";
|
|
576
|
+
const components = isObject(converted.components) ? converted.components : {};
|
|
577
|
+
components.securitySchemes = {
|
|
578
|
+
...isObject(components.securitySchemes) ? components.securitySchemes : {},
|
|
579
|
+
bearerAuth: {
|
|
580
|
+
type: "http",
|
|
581
|
+
scheme: "bearer"
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
converted.components = components;
|
|
585
|
+
stripNoContentResponseBodies(converted);
|
|
586
|
+
return converted;
|
|
587
|
+
}
|
|
588
|
+
async function generateORPCOpenAPISpec(options) {
|
|
589
|
+
const [{ OpenAPIGenerator }, { ZodToJsonSchemaConverter }] = await Promise.all([importRuntimeModule("@orpc/openapi"), importRuntimeModule("@orpc/zod/zod4")]);
|
|
590
|
+
const generator = new OpenAPIGenerator({ schemaConverters: [new ZodToJsonSchemaConverter()] });
|
|
591
|
+
const explicitSchemaName = options.getOpenApiSchemaName ?? getOpenApiSchemaName;
|
|
592
|
+
const modelSchemas = await collectModelSchemaExports({
|
|
593
|
+
apiRoot: options.apiRoot,
|
|
594
|
+
dbTablesRoot: options.dbTablesRoot
|
|
595
|
+
});
|
|
596
|
+
const getSchemaName = createModelSchemaNameGetter(modelSchemas, explicitSchemaName);
|
|
597
|
+
const operationMeta = collectOperationMeta(options.contract);
|
|
598
|
+
const extraSchemas = collectExtraSchemas(options.apiModules);
|
|
599
|
+
const reachableModelSchemas = await collectReachableModelSchemas(options.contract, {
|
|
600
|
+
apiRoot: options.apiRoot,
|
|
601
|
+
dbTablesRoot: options.dbTablesRoot,
|
|
602
|
+
excludedSchemas: collectSchemaRegistryRoots(extraSchemas),
|
|
603
|
+
getOpenApiSchemaName: getSchemaName,
|
|
604
|
+
modelSchemas
|
|
605
|
+
});
|
|
606
|
+
const commonSchemas = {
|
|
607
|
+
...collectContractSchemas(options.contract, [], {}, getSchemaName),
|
|
608
|
+
...extraSchemas,
|
|
609
|
+
...reachableModelSchemas
|
|
610
|
+
};
|
|
611
|
+
const spec = await generator.generate(options.contract, {
|
|
612
|
+
info: options.info ?? {
|
|
613
|
+
title: "Tiny Template Fake API",
|
|
614
|
+
description: "OpenAPI spec generated from the oRPC fake backend contract.",
|
|
615
|
+
version: "3.0.0"
|
|
616
|
+
},
|
|
617
|
+
servers: options.servers ?? [{
|
|
618
|
+
url: "/",
|
|
619
|
+
description: "Current origin"
|
|
620
|
+
}],
|
|
621
|
+
...Object.keys(commonSchemas).length > 0 ? { commonSchemas } : {}
|
|
622
|
+
});
|
|
623
|
+
const jsonSpec = spec;
|
|
624
|
+
const sortableSchemaNames = options.realBackendSortableSchemaNames instanceof Map ? options.realBackendSortableSchemaNames : new Map(Object.entries(options.realBackendSortableSchemaNames ?? {}));
|
|
625
|
+
applyOperationMeta(jsonSpec, operationMeta, options.apiModules);
|
|
626
|
+
applyEnumExtensions(spec);
|
|
627
|
+
applyParameterExtensions(jsonSpec, sortableSchemaNames);
|
|
628
|
+
applyPaginatedItemSchemas(jsonSpec);
|
|
629
|
+
const userRoles = options.userRoles ?? [];
|
|
630
|
+
const defaultRobodevRoles = userRoles.filter((role) => role.isDefault).map((role) => role.name);
|
|
631
|
+
const operationTags = collectOperationTags(jsonSpec);
|
|
632
|
+
const robodevModuleExtensions = /* @__PURE__ */ new Map();
|
|
633
|
+
for (const [name, module] of Object.entries(options.apiModules)) {
|
|
634
|
+
const tagName = getModuleOpenApiTag(options.apiModules, name);
|
|
635
|
+
const hidden = module.robodevHidden === true;
|
|
636
|
+
const explicitRobodevRoles = Array.isArray(module.robodevRoles) ? [...module.robodevRoles] : null;
|
|
637
|
+
const metadata = {
|
|
638
|
+
hidden,
|
|
639
|
+
tables: Array.isArray(module.robodevOwnedTables) ? [...module.robodevOwnedTables] : [],
|
|
640
|
+
roles: getRobodevModuleRoles(hidden, explicitRobodevRoles, operationTags.has(tagName), defaultRobodevRoles)
|
|
641
|
+
};
|
|
642
|
+
if (metadata.hidden || metadata.tables.length > 0 || metadata.roles.length > 0) robodevModuleExtensions.set(name, metadata);
|
|
643
|
+
}
|
|
644
|
+
applyRobodevModuleExtensions(jsonSpec, robodevModuleExtensions, options.apiModules);
|
|
645
|
+
applyRobodevUserRolesExtension(jsonSpec, userRoles);
|
|
646
|
+
return toOpenAPI30Document(jsonSpec);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
//#endregion
|
|
650
|
+
//#region src/tiny/openapi-source.runner.ts
|
|
651
|
+
function createTinyOpenApiSourceRunner(config) {
|
|
652
|
+
let queue = Promise.resolve();
|
|
653
|
+
const getOutputPath = () => getLocalInputPath(config.input, config.root);
|
|
654
|
+
const runGenerate = async () => {
|
|
655
|
+
const outputPath = getOutputPath();
|
|
656
|
+
if (!outputPath) return;
|
|
657
|
+
const generateOpenApiFileOptions = {
|
|
658
|
+
argv: ["--output", outputPath],
|
|
659
|
+
cwd: config.cwd ?? config.root,
|
|
660
|
+
defaultOutput: outputPath,
|
|
661
|
+
env: config.env ?? process.env
|
|
662
|
+
};
|
|
663
|
+
if (config.generateOpenApiFile) {
|
|
664
|
+
await config.generateOpenApiFile(generateOpenApiFileOptions);
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
const generateOpenApiSpec = config.generateOpenApiSpec ?? await loadOpenApiSpecGenerator(config);
|
|
668
|
+
if (!generateOpenApiSpec) throw new Error("Missing Tiny OpenAPI generator. Pass generateOpenApiFile, generateOpenApiSpec, or generateOpenApiSpecModule.");
|
|
669
|
+
await generateOpenApiFile({
|
|
670
|
+
...generateOpenApiFileOptions,
|
|
671
|
+
generateOpenApiSpec
|
|
672
|
+
});
|
|
673
|
+
};
|
|
674
|
+
const enqueueGenerate = () => {
|
|
675
|
+
const run = queue.catch(() => void 0).then(runGenerate);
|
|
676
|
+
queue = run.then(() => void 0, () => void 0);
|
|
677
|
+
return run;
|
|
678
|
+
};
|
|
679
|
+
return {
|
|
680
|
+
enqueueGenerate,
|
|
681
|
+
getOutputPath
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
function isTinyOpenApiFakeMode(apiMode = process.env.VITE_PUBLIC_API_MODE ?? process.env.EXPO_PUBLIC_API_MODE) {
|
|
685
|
+
return apiMode !== "real";
|
|
686
|
+
}
|
|
687
|
+
function getLocalInputPath(input, root) {
|
|
688
|
+
if (typeof input !== "string" || /^https?:\/\//i.test(input)) return;
|
|
689
|
+
return path.resolve(root, input);
|
|
690
|
+
}
|
|
691
|
+
function normalizeWatchFolders(root, watchFolders = []) {
|
|
692
|
+
return watchFolders.map((folder) => path.isAbsolute(folder) ? folder : path.resolve(root, folder));
|
|
693
|
+
}
|
|
694
|
+
async function loadOpenApiSpecGenerator(config) {
|
|
695
|
+
if (!config.generateOpenApiSpecModule) return;
|
|
696
|
+
const moduleConfig = typeof config.generateOpenApiSpecModule === "string" ? { path: config.generateOpenApiSpecModule } : config.generateOpenApiSpecModule;
|
|
697
|
+
const modulePath = path.isAbsolute(moduleConfig.path) ? moduleConfig.path : path.resolve(config.root, moduleConfig.path);
|
|
698
|
+
const exportName = moduleConfig.exportName ?? "generateTinyOpenApiSpec";
|
|
699
|
+
const generateOpenApiSpec = (await import(pathToFileURL(modulePath).href))[exportName];
|
|
700
|
+
if (typeof generateOpenApiSpec !== "function") throw new Error(`Tiny OpenAPI spec module "${moduleConfig.path}" does not export function "${exportName}".`);
|
|
701
|
+
return generateOpenApiSpec;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
//#endregion
|
|
705
|
+
export { namedControllerActionInputDtoSchema as $, generateORPCOpenAPISpec as A, getOperationController as B, collectReachableModelSchemas as C, defineOpenApiSchemas as D, createModelSchemaNameGetter as E, getModuleOpenApiController as F, isContractProcedure as G, getProcedureInputSchemaRole as H, getModuleOpenApiTag as I, isObject as J, isNullSchema as K, getObjectPropertySchema as L, getComponentSchemas as M, getContractProcedureData as N, findComponentEnumNames as O, getDerivedOperationId as P, modelSchemaNameEntries as Q, getOpenApiSchemaName as R, collectOperationTags as S, compactTagName as T, getRobodevModuleRoles as U, getPaginatedItemSchema as V, getStringEnumValues as W, isZodSchema as X, isProcedureMeta as Y, modelSchemaExportName as Z, collectDbTableModelSchemaExports as _, visitZodSchema as _t, addContractSchema as a, operationKey as at, collectModuleModelSchemaExports as b, applyPaginatedItemSchemas as c, routeHasPathParameters as ct, applyRobodevUserRolesExtension as d, sharedSchemaExportName as dt, namedControllerActionSchema as et, asStringArray as f, stripNoContentResponseBodies as ft, collectDbTableModelSchemaExport as g, toPascalCase as gt, collectContractSchemas as h, toOpenAPIAclRule as ht, normalizeWatchFolders as i, namedOpenApiSchema as it, generateOpenApiFile as j, findEnumNames as k, applyParameterExtensions as l, schemaComponentRef as lt, collectContractSchemaRoots as m, toOpenAPI30Schema as mt, getLocalInputPath as n, namedOpenApiRequestSchema as nt, applyEnumExtensions as o, procedureSchemaName as ot, collectApiModelSchemaExports as p, toOpenAPI30Document as pt, isNullableOnlySchema as q, isTinyOpenApiFakeMode as r, namedOpenApiResponseSchema as rt, applyOperationMeta as s, resolveOpenApiOutputPath as st, createTinyOpenApiSourceRunner as t, namedOpenApiOutputSchema as tt, applyRobodevModuleExtensions as u, schemaExportName as ut, collectExtraSchemas as v, collectSchemaRegistryRoots as w, collectOperationMeta as x, collectModelSchemaExports as y, getOperationAction as z };
|