@alagoni97/cli 0.72.1
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/LICENSE +201 -0
- package/README.md +336 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.mjs +3 -0
- package/bin/run.cmd +3 -0
- package/bin/run.mjs +4 -0
- package/dist/LoggingInterface.d.ts +123 -0
- package/dist/LoggingInterface.js +300 -0
- package/dist/PersistedConfig.d.ts +46 -0
- package/dist/PersistedConfig.js +94 -0
- package/dist/browser/adapters/output.d.ts +69 -0
- package/dist/browser/adapters/output.js +91 -0
- package/dist/browser/config.d.ts +18 -0
- package/dist/browser/config.js +59 -0
- package/dist/browser/generate.d.ts +20 -0
- package/dist/browser/generate.js +129 -0
- package/dist/browser/index.d.ts +17 -0
- package/dist/browser/index.js +26 -0
- package/dist/browser/parser.d.ts +9 -0
- package/dist/browser/parser.js +61 -0
- package/dist/browser/shims/asyncapi-parser.d.ts +30 -0
- package/dist/browser/shims/asyncapi-parser.js +52 -0
- package/dist/browser/shims/fs.d.ts +190 -0
- package/dist/browser/shims/fs.js +188 -0
- package/dist/browser/shims/json-schema-ref-parser.d.ts +73 -0
- package/dist/browser/shims/json-schema-ref-parser.js +246 -0
- package/dist/browser/shims/swagger-parser.d.ts +20 -0
- package/dist/browser/shims/swagger-parser.js +40 -0
- package/dist/codegen/configurationSchemaBuilder.d.ts +15 -0
- package/dist/codegen/configurationSchemaBuilder.js +48 -0
- package/dist/codegen/configurations.d.ts +29 -0
- package/dist/codegen/configurations.js +260 -0
- package/dist/codegen/detection.d.ts +19 -0
- package/dist/codegen/detection.js +174 -0
- package/dist/codegen/errors.d.ts +111 -0
- package/dist/codegen/errors.js +352 -0
- package/dist/codegen/generators/generic/custom.d.ts +75 -0
- package/dist/codegen/generators/generic/custom.js +66 -0
- package/dist/codegen/generators/index.d.ts +14 -0
- package/dist/codegen/generators/index.js +42 -0
- package/dist/codegen/generators/typescript/channels/asyncapi.d.ts +10 -0
- package/dist/codegen/generators/typescript/channels/asyncapi.js +131 -0
- package/dist/codegen/generators/typescript/channels/index.d.ts +8 -0
- package/dist/codegen/generators/typescript/channels/index.js +142 -0
- package/dist/codegen/generators/typescript/channels/openapi.d.ts +9 -0
- package/dist/codegen/generators/typescript/channels/openapi.js +168 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/index.d.ts +7 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/index.js +149 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/publishExchange.d.ts +5 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/publishExchange.js +106 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/publishQueue.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/publishQueue.js +102 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/subscribeQueue.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/amqp/subscribeQueue.js +133 -0
- package/dist/codegen/generators/typescript/channels/protocols/eventsource/express.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/eventsource/express.js +100 -0
- package/dist/codegen/generators/typescript/channels/protocols/eventsource/fetch.d.ts +5 -0
- package/dist/codegen/generators/typescript/channels/protocols/eventsource/fetch.js +144 -0
- package/dist/codegen/generators/typescript/channels/protocols/eventsource/index.d.ts +6 -0
- package/dist/codegen/generators/typescript/channels/protocols/eventsource/index.js +132 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/client.d.ts +10 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/client.js +224 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/common-types.d.ts +14 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/common-types.js +800 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/index.d.ts +8 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/index.js +96 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/security.d.ts +48 -0
- package/dist/codegen/generators/typescript/channels/protocols/http/security.js +491 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/index.d.ts +6 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/index.js +127 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/publish.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/publish.js +108 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/subscribe.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/subscribe.js +154 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/utils.d.ts +11 -0
- package/dist/codegen/generators/typescript/channels/protocols/kafka/utils.js +58 -0
- package/dist/codegen/generators/typescript/channels/protocols/mqtt/index.d.ts +6 -0
- package/dist/codegen/generators/typescript/channels/protocols/mqtt/index.js +113 -0
- package/dist/codegen/generators/typescript/channels/protocols/mqtt/publish.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/mqtt/publish.js +99 -0
- package/dist/codegen/generators/typescript/channels/protocols/mqtt/subscribe.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/mqtt/subscribe.js +186 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/corePublish.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/corePublish.js +90 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/coreReply.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/coreReply.js +142 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/coreRequest.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/coreRequest.js +100 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/coreSubscribe.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/coreSubscribe.js +143 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/index.d.ts +11 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/index.js +224 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/jetstreamPublish.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/jetstreamPublish.js +89 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/jetstreamPullSubscribe.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/jetstreamPullSubscribe.js +146 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/jetstreamPushSubscription.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/jetstreamPushSubscription.js +149 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/utils.d.ts +35 -0
- package/dist/codegen/generators/typescript/channels/protocols/nats/utils.js +120 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/index.d.ts +7 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/index.js +152 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/publish.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/publish.js +64 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/register.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/register.js +115 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/subscribe.d.ts +3 -0
- package/dist/codegen/generators/typescript/channels/protocols/websocket/subscribe.js +151 -0
- package/dist/codegen/generators/typescript/channels/types.d.ts +181 -0
- package/dist/codegen/generators/typescript/channels/types.js +131 -0
- package/dist/codegen/generators/typescript/channels/utils.d.ts +64 -0
- package/dist/codegen/generators/typescript/channels/utils.js +163 -0
- package/dist/codegen/generators/typescript/client/index.d.ts +8 -0
- package/dist/codegen/generators/typescript/client/index.js +61 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/corePublish.d.ts +6 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/corePublish.js +53 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/coreSubscribe.d.ts +6 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/coreSubscribe.js +90 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/jetStreamPullSubscription.d.ts +6 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/jetStreamPullSubscription.js +83 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/jetstreamPublish.d.ts +6 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/jetstreamPublish.js +54 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/jetstreamPushSubscription.d.ts +6 -0
- package/dist/codegen/generators/typescript/client/protocols/nats/jetstreamPushSubscription.js +82 -0
- package/dist/codegen/generators/typescript/client/protocols/nats.d.ts +2 -0
- package/dist/codegen/generators/typescript/client/protocols/nats.js +182 -0
- package/dist/codegen/generators/typescript/client/types.d.ts +49 -0
- package/dist/codegen/generators/typescript/client/types.js +37 -0
- package/dist/codegen/generators/typescript/headers.d.ts +54 -0
- package/dist/codegen/generators/typescript/headers.js +138 -0
- package/dist/codegen/generators/typescript/index.d.ts +7 -0
- package/dist/codegen/generators/typescript/index.js +38 -0
- package/dist/codegen/generators/typescript/models.d.ts +21761 -0
- package/dist/codegen/generators/typescript/models.js +64 -0
- package/dist/codegen/generators/typescript/parameters.d.ts +37 -0
- package/dist/codegen/generators/typescript/parameters.js +101 -0
- package/dist/codegen/generators/typescript/payloads.d.ts +73 -0
- package/dist/codegen/generators/typescript/payloads.js +250 -0
- package/dist/codegen/generators/typescript/types.d.ts +34 -0
- package/dist/codegen/generators/typescript/types.js +70 -0
- package/dist/codegen/generators/typescript/utils.d.ts +38 -0
- package/dist/codegen/generators/typescript/utils.js +195 -0
- package/dist/codegen/index.d.ts +7 -0
- package/dist/codegen/index.js +38 -0
- package/dist/codegen/inputs/asyncapi/generators/headers.d.ts +3 -0
- package/dist/codegen/inputs/asyncapi/generators/headers.js +41 -0
- package/dist/codegen/inputs/asyncapi/generators/parameters.d.ts +14 -0
- package/dist/codegen/inputs/asyncapi/generators/parameters.js +120 -0
- package/dist/codegen/inputs/asyncapi/generators/payloads.d.ts +16 -0
- package/dist/codegen/inputs/asyncapi/generators/payloads.js +124 -0
- package/dist/codegen/inputs/asyncapi/generators/types.d.ts +9 -0
- package/dist/codegen/inputs/asyncapi/generators/types.js +61 -0
- package/dist/codegen/inputs/asyncapi/index.d.ts +1 -0
- package/dist/codegen/inputs/asyncapi/index.js +7 -0
- package/dist/codegen/inputs/asyncapi/parser.d.ts +4 -0
- package/dist/codegen/inputs/asyncapi/parser.js +90 -0
- package/dist/codegen/inputs/index.d.ts +3 -0
- package/dist/codegen/inputs/index.js +19 -0
- package/dist/codegen/inputs/jsonschema/generators/index.d.ts +1 -0
- package/dist/codegen/inputs/jsonschema/generators/index.js +5 -0
- package/dist/codegen/inputs/jsonschema/generators/models.d.ts +7 -0
- package/dist/codegen/inputs/jsonschema/generators/models.js +26 -0
- package/dist/codegen/inputs/jsonschema/index.d.ts +1 -0
- package/dist/codegen/inputs/jsonschema/index.js +7 -0
- package/dist/codegen/inputs/jsonschema/parser.d.ts +31 -0
- package/dist/codegen/inputs/jsonschema/parser.js +128 -0
- package/dist/codegen/inputs/openapi/generators/headers.d.ts +3 -0
- package/dist/codegen/inputs/openapi/generators/headers.js +101 -0
- package/dist/codegen/inputs/openapi/generators/parameters.d.ts +10 -0
- package/dist/codegen/inputs/openapi/generators/parameters.js +852 -0
- package/dist/codegen/inputs/openapi/generators/payloads.d.ts +3 -0
- package/dist/codegen/inputs/openapi/generators/payloads.js +231 -0
- package/dist/codegen/inputs/openapi/generators/types.d.ts +9 -0
- package/dist/codegen/inputs/openapi/generators/types.js +86 -0
- package/dist/codegen/inputs/openapi/index.d.ts +2 -0
- package/dist/codegen/inputs/openapi/index.js +8 -0
- package/dist/codegen/inputs/openapi/parser.d.ts +4 -0
- package/dist/codegen/inputs/openapi/parser.js +115 -0
- package/dist/codegen/inputs/openapi/security.d.ts +56 -0
- package/dist/codegen/inputs/openapi/security.js +193 -0
- package/dist/codegen/modelina/index.d.ts +2 -0
- package/dist/codegen/modelina/index.js +20 -0
- package/dist/codegen/modelina/presets/index.d.ts +3 -0
- package/dist/codegen/modelina/presets/index.js +14 -0
- package/dist/codegen/modelina/presets/primitives.d.ts +34 -0
- package/dist/codegen/modelina/presets/primitives.js +211 -0
- package/dist/codegen/modelina/presets/union.d.ts +33 -0
- package/dist/codegen/modelina/presets/union.js +197 -0
- package/dist/codegen/modelina/presets/validation.d.ts +66 -0
- package/dist/codegen/modelina/presets/validation.js +183 -0
- package/dist/codegen/modelina/types.d.ts +61845 -0
- package/dist/codegen/modelina/types.js +412 -0
- package/dist/codegen/output/filesystem.d.ts +30 -0
- package/dist/codegen/output/filesystem.js +61 -0
- package/dist/codegen/output/index.d.ts +16 -0
- package/dist/codegen/output/index.js +57 -0
- package/dist/codegen/output/memory.d.ts +54 -0
- package/dist/codegen/output/memory.js +81 -0
- package/dist/codegen/output/modelina.d.ts +30 -0
- package/dist/codegen/output/modelina.js +30 -0
- package/dist/codegen/output/types.d.ts +47 -0
- package/dist/codegen/output/types.js +6 -0
- package/dist/codegen/renderer.d.ts +13 -0
- package/dist/codegen/renderer.js +309 -0
- package/dist/codegen/schemaPostProcess.d.ts +25 -0
- package/dist/codegen/schemaPostProcess.js +38 -0
- package/dist/codegen/types.d.ts +285187 -0
- package/dist/codegen/types.js +177 -0
- package/dist/codegen/utils.d.ts +126 -0
- package/dist/codegen/utils.js +373 -0
- package/dist/commands/base.d.ts +18 -0
- package/dist/commands/base.js +59 -0
- package/dist/commands/generate.d.ts +46 -0
- package/dist/commands/generate.js +305 -0
- package/dist/commands/init.d.ts +55 -0
- package/dist/commands/init.js +544 -0
- package/dist/commands/telemetry.d.ts +25 -0
- package/dist/commands/telemetry.js +115 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +35 -0
- package/dist/telemetry/anonymize.d.ts +19 -0
- package/dist/telemetry/anonymize.js +73 -0
- package/dist/telemetry/collector.d.ts +26 -0
- package/dist/telemetry/collector.js +57 -0
- package/dist/telemetry/config.d.ts +32 -0
- package/dist/telemetry/config.js +97 -0
- package/dist/telemetry/events.d.ts +72 -0
- package/dist/telemetry/events.js +5 -0
- package/dist/telemetry/index.d.ts +46 -0
- package/dist/telemetry/index.js +91 -0
- package/dist/telemetry/notice.d.ts +8 -0
- package/dist/telemetry/notice.js +50 -0
- package/dist/telemetry/sender.d.ts +14 -0
- package/dist/telemetry/sender.js +125 -0
- package/dist/utils/gitignore.d.ts +66 -0
- package/dist/utils/gitignore.js +111 -0
- package/dist/utils/inputSource.d.ts +3 -0
- package/dist/utils/inputSource.js +26 -0
- package/dist/utils/refResolvers.d.ts +29 -0
- package/dist/utils/refResolvers.js +83 -0
- package/dist/utils/remoteFetch.d.ts +18 -0
- package/dist/utils/remoteFetch.js +64 -0
- package/oclif.manifest.json +510 -0
- package/package.json +155 -0
|
@@ -0,0 +1,852 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createOpenAPIGenerator = exports.createParameterSchema = exports.convertParameterSchemaToJsonSchema = exports.processOpenAPIParameters = void 0;
|
|
4
|
+
const utils_1 = require("../../../generators/typescript/utils");
|
|
5
|
+
const modelina_1 = require("@asyncapi/modelina");
|
|
6
|
+
// Constants for OpenAPI parameter metadata keys
|
|
7
|
+
const X_PARAMETER_LOCATION = 'x-parameter-location';
|
|
8
|
+
const X_PARAMETER_STYLE = 'x-parameter-style';
|
|
9
|
+
const X_PARAMETER_EXPLODE = 'x-parameter-explode';
|
|
10
|
+
const X_PARAMETER_ALLOW_RESERVED = 'x-parameter-allowReserved';
|
|
11
|
+
const X_PARAMETER_COLLECTION_FORMAT = 'x-parameter-collectionFormat';
|
|
12
|
+
// OpenAPI parameter processor
|
|
13
|
+
function processOpenAPIParameters(openapiDocument) {
|
|
14
|
+
const channelParameters = {};
|
|
15
|
+
for (const [pathKey, pathItem] of Object.entries(openapiDocument.paths ?? {})) {
|
|
16
|
+
for (const [method, operation] of Object.entries(pathItem)) {
|
|
17
|
+
const operationObj = operation;
|
|
18
|
+
// Collect parameters from operation and path-level
|
|
19
|
+
const allParameters = operationObj.parameters ?? [];
|
|
20
|
+
const filteredParams = allParameters.filter((param) => {
|
|
21
|
+
return ['path', 'query'].includes(param.in);
|
|
22
|
+
});
|
|
23
|
+
if (filteredParams.length > 0) {
|
|
24
|
+
const operationId = operationObj.operationId ??
|
|
25
|
+
`${method}${pathKey.replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
26
|
+
// Create schema for the parameters
|
|
27
|
+
const parameterSchema = createParameterSchema(operationId, filteredParams, 'Parameters', pathKey);
|
|
28
|
+
channelParameters[operationId] = {
|
|
29
|
+
schema: parameterSchema.schema,
|
|
30
|
+
schemaId: parameterSchema.schemaId
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
channelParameters
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
exports.processOpenAPIParameters = processOpenAPIParameters;
|
|
40
|
+
// Helper function to convert OpenAPI parameter schema to JSON Schema
|
|
41
|
+
function convertParameterSchemaToJsonSchema(parameter) {
|
|
42
|
+
let schema;
|
|
43
|
+
if (parameter.schema) {
|
|
44
|
+
// OpenAPI 3.x format
|
|
45
|
+
schema = { ...parameter.schema };
|
|
46
|
+
}
|
|
47
|
+
else if (parameter.type) {
|
|
48
|
+
// OpenAPI 2.x format
|
|
49
|
+
schema = {
|
|
50
|
+
type: parameter.type,
|
|
51
|
+
...(parameter.format && { format: parameter.format }),
|
|
52
|
+
...(parameter.enum && { enum: parameter.enum }),
|
|
53
|
+
...(parameter.minimum !== undefined && { minimum: parameter.minimum }),
|
|
54
|
+
...(parameter.maximum !== undefined && { maximum: parameter.maximum }),
|
|
55
|
+
...(parameter.minLength !== undefined && {
|
|
56
|
+
minLength: parameter.minLength
|
|
57
|
+
}),
|
|
58
|
+
...(parameter.maxLength !== undefined && {
|
|
59
|
+
maxLength: parameter.maxLength
|
|
60
|
+
}),
|
|
61
|
+
...(parameter.pattern && { pattern: parameter.pattern })
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Fallback to string type
|
|
66
|
+
schema = { type: 'string' };
|
|
67
|
+
}
|
|
68
|
+
return schema;
|
|
69
|
+
}
|
|
70
|
+
exports.convertParameterSchemaToJsonSchema = convertParameterSchemaToJsonSchema;
|
|
71
|
+
// Create JSON Schema object from parameters
|
|
72
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
73
|
+
function createParameterSchema(operationId, parameters, schemaIdSuffix, path) {
|
|
74
|
+
const properties = {};
|
|
75
|
+
const required = [];
|
|
76
|
+
for (const param of parameters) {
|
|
77
|
+
const paramName = param.name;
|
|
78
|
+
const paramSchema = convertParameterSchemaToJsonSchema(param);
|
|
79
|
+
// Add description if available
|
|
80
|
+
if (param.description) {
|
|
81
|
+
paramSchema.description = param.description;
|
|
82
|
+
}
|
|
83
|
+
// Add parameter location metadata to each individual property
|
|
84
|
+
if (param.in) {
|
|
85
|
+
paramSchema[X_PARAMETER_LOCATION] = param.in;
|
|
86
|
+
}
|
|
87
|
+
if (param.style) {
|
|
88
|
+
paramSchema[X_PARAMETER_STYLE] = param.style;
|
|
89
|
+
}
|
|
90
|
+
if (param.explode !== undefined) {
|
|
91
|
+
paramSchema[X_PARAMETER_EXPLODE] = param.explode;
|
|
92
|
+
}
|
|
93
|
+
if (param.allowReserved) {
|
|
94
|
+
paramSchema[X_PARAMETER_ALLOW_RESERVED] = param.allowReserved;
|
|
95
|
+
}
|
|
96
|
+
// Handle OpenAPI 2.0 collectionFormat for backward compatibility
|
|
97
|
+
if (param.collectionFormat) {
|
|
98
|
+
paramSchema[X_PARAMETER_COLLECTION_FORMAT] = param.collectionFormat;
|
|
99
|
+
}
|
|
100
|
+
properties[paramName] = paramSchema;
|
|
101
|
+
// Check if parameter is required
|
|
102
|
+
if (param.required === true) {
|
|
103
|
+
required.push(paramName);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const schemaId = (0, utils_1.pascalCase)(`${operationId}_${schemaIdSuffix.toLowerCase()}`);
|
|
107
|
+
// Create the complete schema object
|
|
108
|
+
const schemaObj = {
|
|
109
|
+
type: 'object',
|
|
110
|
+
additionalProperties: false,
|
|
111
|
+
properties,
|
|
112
|
+
$id: schemaId,
|
|
113
|
+
$schema: 'http://json-schema.org/draft-07/schema',
|
|
114
|
+
'x-channel-address': path
|
|
115
|
+
};
|
|
116
|
+
// Add required array if there are required parameters
|
|
117
|
+
if (required.length > 0) {
|
|
118
|
+
schemaObj.required = required;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
schema: schemaObj,
|
|
122
|
+
schemaId
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
exports.createParameterSchema = createParameterSchema;
|
|
126
|
+
/**
|
|
127
|
+
* Generate additional content for OpenAPI parameter classes
|
|
128
|
+
*/
|
|
129
|
+
function generateOpenAPIParameterMethods(model) {
|
|
130
|
+
const properties = model.originalInput?.properties ?? {};
|
|
131
|
+
// Collect path and query parameters
|
|
132
|
+
const pathParams = [];
|
|
133
|
+
const queryParams = [];
|
|
134
|
+
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
135
|
+
const paramConfig = processParameterSchema(propName, propSchema);
|
|
136
|
+
if (paramConfig) {
|
|
137
|
+
if (paramConfig.location === 'path') {
|
|
138
|
+
pathParams.push(paramConfig);
|
|
139
|
+
}
|
|
140
|
+
else if (paramConfig.location === 'query') {
|
|
141
|
+
queryParams.push(paramConfig);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (pathParams.length === 0 && queryParams.length === 0) {
|
|
146
|
+
return '';
|
|
147
|
+
}
|
|
148
|
+
// Generate both serialization and deserialization methods
|
|
149
|
+
const serializationMethods = generateSerializationMethods(pathParams, queryParams);
|
|
150
|
+
const deserializationMethods = generateDeserializationMethods(pathParams, queryParams, model);
|
|
151
|
+
const extractPathParametersMethod = pathParams.length > 0
|
|
152
|
+
? generateExtractPathParametersMethod(pathParams, model)
|
|
153
|
+
: '';
|
|
154
|
+
return `${serializationMethods}${deserializationMethods}${extractPathParametersMethod}`;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Process a parameter schema and return configuration for serialization
|
|
158
|
+
*/
|
|
159
|
+
function processParameterSchema(propName, propSchema) {
|
|
160
|
+
const schema = propSchema;
|
|
161
|
+
const location = schema[X_PARAMETER_LOCATION];
|
|
162
|
+
if (!location || !['path', 'query'].includes(location)) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
// Handle OpenAPI 2.0 collectionFormat for backward compatibility
|
|
166
|
+
let style = schema[X_PARAMETER_STYLE];
|
|
167
|
+
let explode = schema[X_PARAMETER_EXPLODE];
|
|
168
|
+
if (schema[X_PARAMETER_COLLECTION_FORMAT]) {
|
|
169
|
+
// Convert OpenAPI 2.0 collectionFormat to OpenAPI 3.0 style/explode
|
|
170
|
+
const converted = convertCollectionFormatToStyleAndExplode(schema[X_PARAMETER_COLLECTION_FORMAT], location);
|
|
171
|
+
style = style ?? converted.style;
|
|
172
|
+
explode = explode !== undefined ? explode : converted.explode;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Use default values for OpenAPI 3.0+
|
|
176
|
+
style = style ?? (location === 'path' ? 'simple' : 'form');
|
|
177
|
+
explode = explode !== undefined ? explode : location === 'query';
|
|
178
|
+
}
|
|
179
|
+
const allowReserved = schema[X_PARAMETER_ALLOW_RESERVED] ?? false;
|
|
180
|
+
return {
|
|
181
|
+
name: propName,
|
|
182
|
+
location,
|
|
183
|
+
style,
|
|
184
|
+
explode,
|
|
185
|
+
allowReserved
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Generate all serialization methods
|
|
190
|
+
*/
|
|
191
|
+
function generateSerializationMethods(pathParams, queryParams) {
|
|
192
|
+
let methods = '';
|
|
193
|
+
// Generate path parameter serialization method
|
|
194
|
+
if (pathParams.length > 0) {
|
|
195
|
+
methods += generatePathSerializationMethod(pathParams);
|
|
196
|
+
}
|
|
197
|
+
// Generate query parameter serialization method
|
|
198
|
+
if (queryParams.length > 0) {
|
|
199
|
+
methods += generateQuerySerializationMethod(queryParams);
|
|
200
|
+
}
|
|
201
|
+
// Generate combined serialization method
|
|
202
|
+
methods += generateUrlSerializationMethod(pathParams.length > 0, queryParams.length > 0);
|
|
203
|
+
return methods;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Generate path parameter serialization method
|
|
207
|
+
*/
|
|
208
|
+
function generatePathSerializationMethod(pathParams) {
|
|
209
|
+
const paramSerializations = pathParams
|
|
210
|
+
.map((param) => generatePathParameterSerialization(param))
|
|
211
|
+
.join('\n');
|
|
212
|
+
return `
|
|
213
|
+
/**
|
|
214
|
+
* Serialize path parameters according to OpenAPI 2.0/3.x specification
|
|
215
|
+
* @returns Record of parameter names to their serialized values for path substitution
|
|
216
|
+
*/
|
|
217
|
+
serializePathParameters(): Record<string, string> {
|
|
218
|
+
const result: Record<string, string> = {};
|
|
219
|
+
|
|
220
|
+
${paramSerializations}
|
|
221
|
+
|
|
222
|
+
return result;
|
|
223
|
+
}`;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Generate query parameter serialization method
|
|
227
|
+
*/
|
|
228
|
+
function generateQuerySerializationMethod(queryParams) {
|
|
229
|
+
const paramSerializations = queryParams
|
|
230
|
+
.map((param) => generateQueryParameterSerialization(param))
|
|
231
|
+
.join('\n');
|
|
232
|
+
return `
|
|
233
|
+
/**
|
|
234
|
+
* Serialize query parameters according to OpenAPI 2.0/3.x specification
|
|
235
|
+
* @returns URLSearchParams object with serialized query parameters
|
|
236
|
+
*/
|
|
237
|
+
serializeQueryParameters(): URLSearchParams {
|
|
238
|
+
const params = new URLSearchParams();
|
|
239
|
+
|
|
240
|
+
${paramSerializations}
|
|
241
|
+
|
|
242
|
+
return params;
|
|
243
|
+
}`;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Generate URL serialization method
|
|
247
|
+
*/
|
|
248
|
+
function generateUrlSerializationMethod(hasPathParams, hasQueryParams) {
|
|
249
|
+
const pathLogic = hasPathParams
|
|
250
|
+
? `
|
|
251
|
+
const pathParams = this.serializePathParameters();
|
|
252
|
+
for (const [name, value] of Object.entries(pathParams)) {
|
|
253
|
+
url = url.replace(new RegExp(\`{\${name}}\`, 'g'), value);
|
|
254
|
+
}`
|
|
255
|
+
: '';
|
|
256
|
+
const queryLogic = hasQueryParams
|
|
257
|
+
? `
|
|
258
|
+
const queryParams = this.serializeQueryParameters();
|
|
259
|
+
const queryString = queryParams.toString();
|
|
260
|
+
if (queryString) {
|
|
261
|
+
url += (url.includes('?') ? '&' : '?') + queryString;
|
|
262
|
+
}`
|
|
263
|
+
: '';
|
|
264
|
+
return `
|
|
265
|
+
/**
|
|
266
|
+
* Get the complete serialized URL with path and query parameters
|
|
267
|
+
* @param basePath The base path template (e.g., '/users/{id}')
|
|
268
|
+
* @returns The complete URL with serialized parameters
|
|
269
|
+
*/
|
|
270
|
+
serializeUrl(basePath: string): string {
|
|
271
|
+
let url = basePath;
|
|
272
|
+
|
|
273
|
+
// Replace path parameters
|
|
274
|
+
${pathLogic}
|
|
275
|
+
|
|
276
|
+
// Add query parameters
|
|
277
|
+
${queryLogic}
|
|
278
|
+
|
|
279
|
+
return url;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Get the channel path with parameters substituted (compatible with AsyncAPI channel interface)
|
|
284
|
+
* @param basePath The base path template (e.g., '/pet/findByStatus/{status}/{categoryId}')
|
|
285
|
+
* @returns The path with parameters replaced
|
|
286
|
+
*/
|
|
287
|
+
getChannelWithParameters(basePath: string): string {
|
|
288
|
+
return this.serializeUrl(basePath);
|
|
289
|
+
}`;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Generate serialization code for a single path parameter
|
|
293
|
+
*/
|
|
294
|
+
function generatePathParameterSerialization(param) {
|
|
295
|
+
const { name, style, explode, allowReserved } = param;
|
|
296
|
+
const encoding = allowReserved ? '' : 'encodeURIComponent';
|
|
297
|
+
return ` // Serialize path parameter: ${name} (style: ${style}, explode: ${explode})
|
|
298
|
+
if (this.${name} !== undefined && this.${name} !== null) {
|
|
299
|
+
const value = this.${name};
|
|
300
|
+
${generatePathSerializationLogic(name, style, explode, encoding)}
|
|
301
|
+
}`;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Generate serialization code for a single query parameter
|
|
305
|
+
*/
|
|
306
|
+
function generateQueryParameterSerialization(param) {
|
|
307
|
+
const { name, style, explode, allowReserved } = param;
|
|
308
|
+
const encoding = allowReserved ? '' : 'encodeURIComponent';
|
|
309
|
+
return ` // Serialize query parameter: ${name} (style: ${style}, explode: ${explode})
|
|
310
|
+
if (this.${name} !== undefined && this.${name} !== null) {
|
|
311
|
+
const value = this.${name};
|
|
312
|
+
${generateQuerySerializationLogic(name, style, explode, encoding)}
|
|
313
|
+
}`;
|
|
314
|
+
}
|
|
315
|
+
// Constants for common serialization patterns
|
|
316
|
+
const RESULT_ASSIGNMENT = "result['";
|
|
317
|
+
const COMMA_SEPARATOR = ".join(',')";
|
|
318
|
+
const DOT_SEPARATOR = ".join('.')";
|
|
319
|
+
/**
|
|
320
|
+
* Generate path parameter serialization logic
|
|
321
|
+
*/
|
|
322
|
+
function generatePathSerializationLogic(name, style, explode, encoding) {
|
|
323
|
+
const encodeValue = encoding ? `${encoding}(String(val))` : 'String(val)';
|
|
324
|
+
const encodeScalarValue = encoding
|
|
325
|
+
? `${encoding}(String(value))`
|
|
326
|
+
: 'String(value)';
|
|
327
|
+
const encodeKey = encoding ? `${encoding}(key)` : 'key';
|
|
328
|
+
switch (style) {
|
|
329
|
+
case 'simple':
|
|
330
|
+
return generateSimpleStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey);
|
|
331
|
+
case 'label':
|
|
332
|
+
return generateLabelStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey);
|
|
333
|
+
case 'matrix':
|
|
334
|
+
return generateMatrixStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey);
|
|
335
|
+
default:
|
|
336
|
+
return `${RESULT_ASSIGNMENT}${name}'] = ${encodeScalarValue};`;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Generate query parameter serialization logic
|
|
341
|
+
*/
|
|
342
|
+
function generateQuerySerializationLogic(name, style, explode, encoding) {
|
|
343
|
+
const encodeValue = encoding ? `${encoding}(String(val))` : 'String(val)';
|
|
344
|
+
const encodeScalarValue = encoding
|
|
345
|
+
? `${encoding}(String(value))`
|
|
346
|
+
: 'String(value)';
|
|
347
|
+
const encodeKey = encoding ? `${encoding}(key)` : 'key';
|
|
348
|
+
switch (style) {
|
|
349
|
+
case 'form':
|
|
350
|
+
return generateFormStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey);
|
|
351
|
+
case 'spaceDelimited':
|
|
352
|
+
return generateSpaceDelimitedLogic(name, explode, encodeValue, encodeScalarValue);
|
|
353
|
+
case 'pipeDelimited':
|
|
354
|
+
return generatePipeDelimitedLogic(name, explode, encodeValue, encodeScalarValue);
|
|
355
|
+
case 'deepObject':
|
|
356
|
+
return generateDeepObjectLogic(name, encodeValue, encodeKey);
|
|
357
|
+
default:
|
|
358
|
+
return `params.append('${name}', ${encodeScalarValue});`;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Generate serialization logic for simple style
|
|
363
|
+
*/
|
|
364
|
+
function generateSimpleStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey) {
|
|
365
|
+
return `if (Array.isArray(value)) {
|
|
366
|
+
${RESULT_ASSIGNMENT}${name}'] = value.map(val => ${encodeValue})${COMMA_SEPARATOR};
|
|
367
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
368
|
+
${explode
|
|
369
|
+
? `${RESULT_ASSIGNMENT}${name}'] = Object.entries(value).map(([key, val]) => \`\${${encodeKey}}=\${${encodeValue}}\`)${COMMA_SEPARATOR};`
|
|
370
|
+
: `${RESULT_ASSIGNMENT}${name}'] = Object.entries(value).map(([key, val]) => \`\${${encodeKey}},\${${encodeValue}}\`)${COMMA_SEPARATOR};`}
|
|
371
|
+
} else {
|
|
372
|
+
${RESULT_ASSIGNMENT}${name}'] = ${encodeScalarValue};
|
|
373
|
+
}`;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Generate serialization logic for label style
|
|
377
|
+
*/
|
|
378
|
+
function generateLabelStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey) {
|
|
379
|
+
return `if (Array.isArray(value)) {
|
|
380
|
+
${explode
|
|
381
|
+
? `${RESULT_ASSIGNMENT}${name}'] = '.' + value.map(val => ${encodeValue})${DOT_SEPARATOR};`
|
|
382
|
+
: `${RESULT_ASSIGNMENT}${name}'] = '.' + value.map(val => ${encodeValue})${COMMA_SEPARATOR};`}
|
|
383
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
384
|
+
${explode
|
|
385
|
+
? `${RESULT_ASSIGNMENT}${name}'] = '.' + Object.entries(value).map(([key, val]) => \`\${${encodeKey}}=\${${encodeValue}}\`)${DOT_SEPARATOR};`
|
|
386
|
+
: `${RESULT_ASSIGNMENT}${name}'] = '.' + Object.entries(value).map(([key, val]) => \`\${${encodeKey}},\${${encodeValue}}\`)${COMMA_SEPARATOR};`}
|
|
387
|
+
} else {
|
|
388
|
+
${RESULT_ASSIGNMENT}${name}'] = '.' + ${encodeScalarValue};
|
|
389
|
+
}`;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Generate serialization logic for matrix style
|
|
393
|
+
*/
|
|
394
|
+
function generateMatrixStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey) {
|
|
395
|
+
return `if (Array.isArray(value)) {
|
|
396
|
+
${explode
|
|
397
|
+
? `${RESULT_ASSIGNMENT}${name}'] = value.map(val => \`;${name}=\${${encodeValue}}\`).join('');`
|
|
398
|
+
: `${RESULT_ASSIGNMENT}${name}'] = \`;${name}=\` + value.map(val => ${encodeValue})${COMMA_SEPARATOR};`}
|
|
399
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
400
|
+
${explode
|
|
401
|
+
? `${RESULT_ASSIGNMENT}${name}'] = Object.entries(value).map(([key, val]) => \`;\${${encodeKey}}=\${${encodeValue}}\`).join('');`
|
|
402
|
+
: `${RESULT_ASSIGNMENT}${name}'] = \`;${name}=\` + Object.entries(value).map(([key, val]) => \`\${${encodeKey}},\${${encodeValue}}\`)${COMMA_SEPARATOR};`}
|
|
403
|
+
} else {
|
|
404
|
+
${RESULT_ASSIGNMENT}${name}'] = \`;${name}=\` + ${encodeScalarValue};
|
|
405
|
+
}`;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Generate serialization logic for form style
|
|
409
|
+
*/
|
|
410
|
+
function generateFormStyleLogic(name, explode, encodeValue, encodeScalarValue, encodeKey) {
|
|
411
|
+
return `if (Array.isArray(value)) {
|
|
412
|
+
${explode
|
|
413
|
+
? `value.forEach(val => params.append('${name}', ${encodeValue}));`
|
|
414
|
+
: `params.append('${name}', value.map(val => ${encodeValue}).join(','));`}
|
|
415
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
416
|
+
${explode
|
|
417
|
+
? `Object.entries(value).forEach(([key, val]) => params.append(${encodeKey}, ${encodeValue}));`
|
|
418
|
+
: `params.append('${name}', Object.entries(value).map(([key, val]) => \`\${${encodeKey}},\${${encodeValue}}\`).join(','));`}
|
|
419
|
+
} else {
|
|
420
|
+
params.append('${name}', ${encodeScalarValue});
|
|
421
|
+
}`;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Generate serialization logic for space delimited style
|
|
425
|
+
*/
|
|
426
|
+
function generateSpaceDelimitedLogic(name, explode, encodeValue, encodeScalarValue) {
|
|
427
|
+
return `if (Array.isArray(value)) {
|
|
428
|
+
${explode
|
|
429
|
+
? `value.forEach(val => params.append('${name}', ${encodeValue}));`
|
|
430
|
+
: `params.append('${name}', value.map(val => ${encodeValue}).join(' '));`}
|
|
431
|
+
} else {
|
|
432
|
+
params.append('${name}', ${encodeScalarValue});
|
|
433
|
+
}`;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Generate serialization logic for pipe delimited style
|
|
437
|
+
*/
|
|
438
|
+
function generatePipeDelimitedLogic(name, explode, encodeValue, encodeScalarValue) {
|
|
439
|
+
return `if (Array.isArray(value)) {
|
|
440
|
+
${explode
|
|
441
|
+
? `value.forEach(val => params.append('${name}', ${encodeValue}));`
|
|
442
|
+
: `params.append('${name}', value.map(val => ${encodeValue}).join('|'));`}
|
|
443
|
+
} else {
|
|
444
|
+
params.append('${name}', ${encodeScalarValue});
|
|
445
|
+
}`;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Generate serialization logic for deep object style
|
|
449
|
+
*/
|
|
450
|
+
function generateDeepObjectLogic(name, encodeValue, encodeKey) {
|
|
451
|
+
return `if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
452
|
+
Object.entries(value).forEach(([key, val]) => {
|
|
453
|
+
params.append(\`${name}[\${key}]\`, ${encodeValue});
|
|
454
|
+
});
|
|
455
|
+
} else {
|
|
456
|
+
params.append('${name}', String(value));
|
|
457
|
+
}`;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Convert OpenAPI 2.0 collectionFormat to OpenAPI 3.0 style and explode
|
|
461
|
+
*/
|
|
462
|
+
function convertCollectionFormatToStyleAndExplode(collectionFormat, location) {
|
|
463
|
+
switch (collectionFormat) {
|
|
464
|
+
case 'csv':
|
|
465
|
+
return { style: location === 'query' ? 'form' : 'simple', explode: false };
|
|
466
|
+
case 'ssv':
|
|
467
|
+
return { style: 'spaceDelimited', explode: false };
|
|
468
|
+
case 'tsv':
|
|
469
|
+
// TSV not directly supported in OpenAPI 3.0, treat as csv
|
|
470
|
+
return { style: location === 'query' ? 'form' : 'simple', explode: false };
|
|
471
|
+
case 'pipes':
|
|
472
|
+
return { style: 'pipeDelimited', explode: false };
|
|
473
|
+
case 'multi':
|
|
474
|
+
return { style: 'form', explode: true };
|
|
475
|
+
default:
|
|
476
|
+
return { style: location === 'query' ? 'form' : 'simple', explode: false };
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Generate all deserialization methods
|
|
481
|
+
*/
|
|
482
|
+
function generateDeserializationMethods(pathParams, queryParams, model) {
|
|
483
|
+
let methods = '';
|
|
484
|
+
// Generate URL deserialization method
|
|
485
|
+
if (queryParams.length > 0) {
|
|
486
|
+
methods += generateUrlDeserializationMethod(queryParams, model);
|
|
487
|
+
}
|
|
488
|
+
// Generate static fromUrl method
|
|
489
|
+
methods += generateFromUrlStaticMethod(pathParams, model);
|
|
490
|
+
return methods;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Generate URL deserialization method
|
|
494
|
+
*/
|
|
495
|
+
function generateUrlDeserializationMethod(queryParams, model) {
|
|
496
|
+
const paramDeserializations = queryParams
|
|
497
|
+
.map((param) => generateQueryParameterDeserialization(param, model))
|
|
498
|
+
.join('\n');
|
|
499
|
+
return `
|
|
500
|
+
/**
|
|
501
|
+
* Deserialize URL and populate instance properties from query parameters
|
|
502
|
+
* @param url The URL to parse (can be full URL or just query string)
|
|
503
|
+
*/
|
|
504
|
+
deserializeUrl(url: string): void {
|
|
505
|
+
// Extract query string from URL
|
|
506
|
+
let queryString = '';
|
|
507
|
+
if (url.includes('?')) {
|
|
508
|
+
queryString = url.split('?')[1];
|
|
509
|
+
} else if (url.includes('=')) {
|
|
510
|
+
// Assume it's already a query string
|
|
511
|
+
queryString = url;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if (!queryString) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const params = new URLSearchParams(queryString);
|
|
519
|
+
|
|
520
|
+
${paramDeserializations}
|
|
521
|
+
}`;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Generate static fromUrl method
|
|
525
|
+
*/
|
|
526
|
+
function generateFromUrlStaticMethod(pathParams, model) {
|
|
527
|
+
const properties = model.originalInput?.properties ?? {};
|
|
528
|
+
const requiredParams = [];
|
|
529
|
+
// Find required parameters to determine constructor defaults
|
|
530
|
+
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
531
|
+
const paramConfig = processParameterSchema(propName, propSchema);
|
|
532
|
+
if (paramConfig && model.originalInput?.required?.includes(propName)) {
|
|
533
|
+
requiredParams.push(propName);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
// Generate path parameter extraction logic
|
|
537
|
+
const pathParamExtraction = pathParams.length > 0 ? generatePathParameterExtraction(pathParams) : '';
|
|
538
|
+
// Generate constructor arguments with path parameters first, then required non-path parameters
|
|
539
|
+
const pathParamArgs = pathParams
|
|
540
|
+
.map((param) => `${param.name}: pathParams.${param.name}`)
|
|
541
|
+
.join(', ');
|
|
542
|
+
const requiredNonPathParams = requiredParams.filter((param) => !pathParams.some((pathParam) => pathParam.name === param));
|
|
543
|
+
const requiredParamArgs = requiredNonPathParams
|
|
544
|
+
.map((param) => `${param}: default${(0, utils_1.pascalCase)(param)}`)
|
|
545
|
+
.join(', ');
|
|
546
|
+
let constructorArgs = '';
|
|
547
|
+
if (pathParamArgs && requiredParamArgs) {
|
|
548
|
+
constructorArgs = `${pathParamArgs}, ${requiredParamArgs}`;
|
|
549
|
+
}
|
|
550
|
+
else if (pathParamArgs) {
|
|
551
|
+
constructorArgs = pathParamArgs;
|
|
552
|
+
}
|
|
553
|
+
else if (requiredParamArgs) {
|
|
554
|
+
constructorArgs = requiredParamArgs;
|
|
555
|
+
}
|
|
556
|
+
// Generate parameter documentation
|
|
557
|
+
const paramDocs = requiredNonPathParams.length > 0
|
|
558
|
+
? requiredNonPathParams
|
|
559
|
+
.map((param) => ` * @param default${(0, utils_1.pascalCase)(param)} Default ${param} values (required parameter)`)
|
|
560
|
+
.join('\n')
|
|
561
|
+
: '';
|
|
562
|
+
// Generate function parameters
|
|
563
|
+
const functionParams = requiredNonPathParams.length > 0
|
|
564
|
+
? requiredNonPathParams
|
|
565
|
+
.map((param) => `, default${(0, utils_1.pascalCase)(param)}: ${getParameterType(properties[param])} = ${generateDefaultValue(properties[param], param)}`)
|
|
566
|
+
.join('')
|
|
567
|
+
: '';
|
|
568
|
+
return `
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Static method to create a new instance from a URL
|
|
572
|
+
* @param url The URL to parse
|
|
573
|
+
* @param basePath The base path template (e.g., '/pet/findByStatus/{status}/{categoryId}')
|
|
574
|
+
${paramDocs}
|
|
575
|
+
* @returns A new ${model.type} instance
|
|
576
|
+
*/
|
|
577
|
+
static fromUrl(url: string, basePath: string${functionParams}): ${model.type} {
|
|
578
|
+
${pathParamExtraction}
|
|
579
|
+
const instance = new ${model.type}({ ${constructorArgs} });
|
|
580
|
+
instance.deserializeUrl(url);
|
|
581
|
+
return instance;
|
|
582
|
+
}`;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Generate path parameter extraction logic for the fromUrl method
|
|
586
|
+
*/
|
|
587
|
+
function generatePathParameterExtraction(pathParams) {
|
|
588
|
+
if (pathParams.length === 0) {
|
|
589
|
+
return '';
|
|
590
|
+
}
|
|
591
|
+
return `// Extract path parameters from URL
|
|
592
|
+
const pathParams = this.extractPathParameters(url, basePath);`;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Generate deserialization code for a single query parameter
|
|
596
|
+
*/
|
|
597
|
+
function generateQueryParameterDeserialization(param, model) {
|
|
598
|
+
const { name, style, explode } = param;
|
|
599
|
+
const properties = model.originalInput?.properties ?? {};
|
|
600
|
+
const propSchema = properties[name];
|
|
601
|
+
const logicCode = generateQueryDeserializationLogic(name, style, explode, propSchema);
|
|
602
|
+
return ` // Deserialize query parameter: ${name} (style: ${style}, explode: ${explode})
|
|
603
|
+
if (params.has('${name}')) {
|
|
604
|
+
const value = params.get('${name}');
|
|
605
|
+
${logicCode}
|
|
606
|
+
}`;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Generate query parameter deserialization logic
|
|
610
|
+
*/
|
|
611
|
+
function generateQueryDeserializationLogic(name, style, explode, propSchema) {
|
|
612
|
+
const isArray = propSchema?.type === 'array' || propSchema?.items;
|
|
613
|
+
const isBoolean = propSchema?.type === 'boolean';
|
|
614
|
+
const isNumber = propSchema?.type === 'integer' || propSchema?.type === 'number';
|
|
615
|
+
const paramType = getParameterType(propSchema);
|
|
616
|
+
switch (style) {
|
|
617
|
+
case 'form':
|
|
618
|
+
return generateFormStyleDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType);
|
|
619
|
+
case 'spaceDelimited':
|
|
620
|
+
return generateSpaceDelimitedDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType);
|
|
621
|
+
case 'pipeDelimited':
|
|
622
|
+
return generatePipeDelimitedDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType);
|
|
623
|
+
case 'deepObject':
|
|
624
|
+
return generateDeepObjectDeserializationLogic(name, isBoolean, isNumber, paramType);
|
|
625
|
+
default:
|
|
626
|
+
throw new Error(`Unsupported style: ${style}`);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Generate deserialization logic for form style
|
|
631
|
+
*/
|
|
632
|
+
function generateFormStyleDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType) {
|
|
633
|
+
if (isArray && !explode) {
|
|
634
|
+
const typecast = paramType.includes('[]') ? ` as ${paramType}` : '';
|
|
635
|
+
return `if (value === '') {
|
|
636
|
+
this.${name} = [];
|
|
637
|
+
} else if (value) {
|
|
638
|
+
// Split by comma and decode
|
|
639
|
+
const decodedValues = value.split(',').map(val => decodeURIComponent(val.trim()));
|
|
640
|
+
this.${name} = decodedValues${typecast};
|
|
641
|
+
}`;
|
|
642
|
+
}
|
|
643
|
+
else if (isArray && explode) {
|
|
644
|
+
const typecast = paramType.includes('[]') ? ` as ${paramType}` : '';
|
|
645
|
+
return `const allValues = params.getAll('${name}');
|
|
646
|
+
if (allValues.length > 0) {
|
|
647
|
+
const decodedValues = allValues.map(val => decodeURIComponent(val));
|
|
648
|
+
this.${name} = decodedValues${typecast};
|
|
649
|
+
}`;
|
|
650
|
+
}
|
|
651
|
+
else if (isBoolean) {
|
|
652
|
+
return `if (value) {
|
|
653
|
+
const decodedValue = decodeURIComponent(value);
|
|
654
|
+
this.${name} = decodedValue.toLowerCase() === 'true';
|
|
655
|
+
}`;
|
|
656
|
+
}
|
|
657
|
+
else if (isNumber) {
|
|
658
|
+
return `if (value) {
|
|
659
|
+
const decodedValue = decodeURIComponent(value);
|
|
660
|
+
const numValue = Number(decodedValue);
|
|
661
|
+
if (!isNaN(numValue)) {
|
|
662
|
+
this.${name} = numValue;
|
|
663
|
+
}
|
|
664
|
+
}`;
|
|
665
|
+
}
|
|
666
|
+
const typecast = paramType !== 'string' && paramType !== 'string | undefined'
|
|
667
|
+
? ` as ${paramType.replace(' | undefined', '')}`
|
|
668
|
+
: '';
|
|
669
|
+
return `if (value) {
|
|
670
|
+
const decodedValue = decodeURIComponent(value);
|
|
671
|
+
this.${name} = decodedValue${typecast};
|
|
672
|
+
}`;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Generate deserialization logic for space delimited style
|
|
676
|
+
*/
|
|
677
|
+
function generateSpaceDelimitedDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType) {
|
|
678
|
+
if (isArray && !explode) {
|
|
679
|
+
const typecast = paramType.includes('[]') ? ` as ${paramType}` : '';
|
|
680
|
+
return `if (value === '') {
|
|
681
|
+
this.${name} = [];
|
|
682
|
+
} else if (value) {
|
|
683
|
+
// Split by space and decode
|
|
684
|
+
const decodedValues = value.split(' ').map(val => decodeURIComponent(val.trim()));
|
|
685
|
+
this.${name} = decodedValues${typecast};
|
|
686
|
+
}`;
|
|
687
|
+
}
|
|
688
|
+
return generateFormStyleDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType);
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Generate deserialization logic for pipe delimited style
|
|
692
|
+
*/
|
|
693
|
+
function generatePipeDelimitedDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType) {
|
|
694
|
+
if (isArray && !explode) {
|
|
695
|
+
const typecast = paramType.includes('[]') ? ` as ${paramType}` : '';
|
|
696
|
+
return `if (value === '') {
|
|
697
|
+
this.${name} = [];
|
|
698
|
+
} else if (value) {
|
|
699
|
+
// Split by pipe and decode
|
|
700
|
+
const decodedValues = value.split('|').map(val => decodeURIComponent(val.trim()));
|
|
701
|
+
this.${name} = decodedValues${typecast};
|
|
702
|
+
}`;
|
|
703
|
+
}
|
|
704
|
+
return generateFormStyleDeserializationLogic(name, explode, isArray, isBoolean, isNumber, paramType);
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Generate deserialization logic for deep object style
|
|
708
|
+
*/
|
|
709
|
+
function generateDeepObjectDeserializationLogic(name, isBoolean, isNumber, paramType) {
|
|
710
|
+
const nameLength = name.length + 1;
|
|
711
|
+
const typecast = paramType !== 'any' && paramType !== 'any | undefined'
|
|
712
|
+
? ` as ${paramType.replace(' | undefined', '')}`
|
|
713
|
+
: '';
|
|
714
|
+
return `// Deep object style deserialization
|
|
715
|
+
const deepObjectParams: {[key: string]: any} = {};
|
|
716
|
+
for (const [paramName, paramValue] of params.entries()) {
|
|
717
|
+
if (paramName.startsWith('${name}[') && paramName.endsWith(']')) {
|
|
718
|
+
const key = paramName.slice(${nameLength}, -1);
|
|
719
|
+
deepObjectParams[key] = decodeURIComponent(paramValue);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
if (Object.keys(deepObjectParams).length > 0) {
|
|
723
|
+
this.${name} = deepObjectParams${typecast};
|
|
724
|
+
}`;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Get parameter type for TypeScript casting
|
|
728
|
+
*/
|
|
729
|
+
function getParameterType(propSchema) {
|
|
730
|
+
if (!propSchema) {
|
|
731
|
+
return 'any';
|
|
732
|
+
}
|
|
733
|
+
if (propSchema.type === 'array') {
|
|
734
|
+
const itemType = propSchema.items?.type || 'string';
|
|
735
|
+
const enumValues = propSchema.items?.enum;
|
|
736
|
+
if (enumValues) {
|
|
737
|
+
const enumTypes = enumValues.map((v) => `"${v}"`).join(' | ');
|
|
738
|
+
return `(${enumTypes})[]`;
|
|
739
|
+
}
|
|
740
|
+
return `${itemType}[]`;
|
|
741
|
+
}
|
|
742
|
+
else if (propSchema.enum) {
|
|
743
|
+
return propSchema.enum.map((v) => `"${v}"`).join(' | ');
|
|
744
|
+
}
|
|
745
|
+
else if (propSchema.type === 'integer' || propSchema.type === 'number') {
|
|
746
|
+
return 'number';
|
|
747
|
+
}
|
|
748
|
+
else if (propSchema.type === 'boolean') {
|
|
749
|
+
return 'boolean';
|
|
750
|
+
}
|
|
751
|
+
return 'string';
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Generate default value for required parameters
|
|
755
|
+
*/
|
|
756
|
+
function generateDefaultValue(propSchema, paramName) {
|
|
757
|
+
if (!propSchema) {
|
|
758
|
+
return '[]';
|
|
759
|
+
}
|
|
760
|
+
if (propSchema.type === 'array') {
|
|
761
|
+
return '[]';
|
|
762
|
+
}
|
|
763
|
+
else if (propSchema.type === 'boolean') {
|
|
764
|
+
return 'false';
|
|
765
|
+
}
|
|
766
|
+
else if (propSchema.type === 'integer' || propSchema.type === 'number') {
|
|
767
|
+
return propSchema.default?.toString() || '0';
|
|
768
|
+
}
|
|
769
|
+
else if (propSchema.enum && propSchema.default) {
|
|
770
|
+
return `"${propSchema.default}"`;
|
|
771
|
+
}
|
|
772
|
+
else if (propSchema.enum) {
|
|
773
|
+
return `"${propSchema.enum[0]}"`;
|
|
774
|
+
}
|
|
775
|
+
return propSchema.default ? `"${propSchema.default}"` : '""';
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Generate the extractPathParameters static method
|
|
779
|
+
*/
|
|
780
|
+
function generateExtractPathParametersMethod(pathParams, model) {
|
|
781
|
+
const properties = model.originalInput?.properties ?? {};
|
|
782
|
+
const paramExtractions = pathParams
|
|
783
|
+
.map((param) => {
|
|
784
|
+
const propSchema = properties[param.name];
|
|
785
|
+
const isNumber = propSchema?.type === 'integer' || propSchema?.type === 'number';
|
|
786
|
+
const conversion = isNumber ? 'Number(decodeValue)' : 'decodeValue';
|
|
787
|
+
const paramType = getParameterType(propSchema);
|
|
788
|
+
const typecast = paramType !== 'string' ? ` as ${paramType}` : '';
|
|
789
|
+
return ` case '${param.name}':
|
|
790
|
+
result.${param.name} = ${conversion}${typecast};
|
|
791
|
+
break;`;
|
|
792
|
+
})
|
|
793
|
+
.join('\n');
|
|
794
|
+
return `
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Extract path parameters from a URL using a base path template
|
|
798
|
+
* @param url The URL to extract parameters from
|
|
799
|
+
* @param basePath The base path template (e.g., '/pet/findByStatus/{status}/{categoryId}')
|
|
800
|
+
* @returns Object containing extracted path parameter values
|
|
801
|
+
*/
|
|
802
|
+
private static extractPathParameters(url: string, basePath: string): { ${pathParams.map((p) => `${p.name}: ${getParameterType(properties[p.name])}`).join(', ')} } {
|
|
803
|
+
// Remove query string from URL for path matching
|
|
804
|
+
const urlPath = url.split('?')[0];
|
|
805
|
+
|
|
806
|
+
// Create regex pattern from base path template
|
|
807
|
+
const regexPattern = basePath.replace(/\\{([^}]+)\\}/g, '([^/]+)');
|
|
808
|
+
const regex = new RegExp('^' + regexPattern + '$');
|
|
809
|
+
|
|
810
|
+
const match = urlPath.match(regex);
|
|
811
|
+
if (!match) {
|
|
812
|
+
throw new Error(\`URL path '\${urlPath}' does not match base path template '\${basePath}'\`);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// Extract parameter names from base path template
|
|
816
|
+
const paramNames = basePath.match(/\\{([^}]+)\\}/g)?.map(p => p.slice(1, -1)) || [];
|
|
817
|
+
|
|
818
|
+
// Map matched values to parameter names
|
|
819
|
+
const result: any = {};
|
|
820
|
+
paramNames.forEach((paramName, index) => {
|
|
821
|
+
const rawValue = match[index + 1];
|
|
822
|
+
const decodeValue = decodeURIComponent(rawValue);
|
|
823
|
+
switch (paramName) {
|
|
824
|
+
${paramExtractions}
|
|
825
|
+
default:
|
|
826
|
+
result[paramName] = decodeValue;
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
return result;
|
|
831
|
+
}`;
|
|
832
|
+
}
|
|
833
|
+
function createOpenAPIGenerator() {
|
|
834
|
+
return new modelina_1.TypeScriptFileGenerator({
|
|
835
|
+
...utils_1.defaultCodegenTypescriptModelinaOptions,
|
|
836
|
+
enumType: 'union',
|
|
837
|
+
useJavascriptReservedKeywords: false,
|
|
838
|
+
presets: [
|
|
839
|
+
modelina_1.TS_DESCRIPTION_PRESET,
|
|
840
|
+
{
|
|
841
|
+
class: {
|
|
842
|
+
additionalContent: ({ content, model }) => {
|
|
843
|
+
const additionalMethods = generateOpenAPIParameterMethods(model);
|
|
844
|
+
return `${content}
|
|
845
|
+
${additionalMethods}`;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
]
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
exports.createOpenAPIGenerator = createOpenAPIGenerator;
|